Динамический SQL-запрос (записи переменных и записи переменных на столбец) - PullRequest
0 голосов
/ 16 июля 2010

Извините за длинный пост, но большая часть кода - это сценарий, описывающий мой сценарий:

Я пытаюсь выполнить динамический запрос (возможно, через сохраненную процедуру) для получениярезультаты, основанные на переменном количестве входных данных.

Если у меня была таблица:

(dbo).(People)
ID   Name   Age
1    Joe    28
2    Bob    32
3    Alan   26
4    Joe    27

Я хочу разрешить пользователю выполнять поиск по любому из трех столбцов, без проблем:

DECLARE @ID int, @Name nvarchar(25), @Age int
SET @ID = 1
SET @Name = 'Joe'
SET @Age = null

SELECT *
FROM dbo.People
WHERE
(ID = @ID or @ID is null) AND
(Name like @Name or @Name is null) AND
(Age = @Age or @Age is null)

И я получаю желаемый результат.

Теперь, если я хочу найти несколько полей в столбце, я могу сделать это без проблем:

DECLARE @text nvarchar(100)
SET @text = '1, 3'

DECLARE @ids AS TABLE (n int NOT NULL PRIMARY KEY)

--//parse the string into a table
DECLARE @TempString nvarchar(300), @Pos int
SET @text = LTRIM(RTRIM(@text))+ ','
SET @Pos = CHARINDEX(',', @text, 1)
IF REPLACE(@text, ',', '') <> ''
BEGIN
    WHILE @Pos > 0
    BEGIN
        SET @TempString = LTRIM(RTRIM(LEFT(@text, @Pos - 1)))
        IF @TempString <> '' --just: IF @TempString != ''
        BEGIN
            INSERT INTO @ids VALUES (@TempString)
        END
        SET @text = RIGHT(@text, LEN(@text) - @Pos)
        SET @Pos = CHARINDEX(',', @text, 1)
    END
END


SELECT *
FROM   dbo.People
WHERE  
ID IN (SELECT n FROM @ids)

Теперь моя проблема в том, что я не могу понять, как объединить два, поскольку не могу поставить:

WHERE
(Name like @Name or @Name is null) AND
(Id IN (SELECT n FROM @ids) or @ids is null)

Поскольку @ids никогда не будет нулевым (так как это таблица)

Любая помощь будет принята с благодарностью!

Заранее спасибо ... и дайте мне знать, если я смогу что-то уточнить

Ответы [ 4 ]

1 голос
/ 16 июля 2010

Вы можете использовать оператор IF:

IF LEN(@ids) > 0
BEGIN

  SELECT *
    FROM dbo.People
   WHERE ID IN (SELECT n FROM @ids)

END
ELSE
BEGIN

  SELECT *
    FROM dbo.People

END

В противном случае рассмотрите возможность превращения запроса в настоящий динамический SQL (не забывая, конечно, об ловушках) .

0 голосов
/ 16 июля 2010

Быстрое исправление:

(`%,' + Id + ',%' like ',' + @ids + ',' or @ids is null)
and (`%,' + Name + ',%' like ',' + @names + ',' or @names is null)

Поэтому, если пользователь передает @ids = 1,2, первая строка дает:

`%,1,%' like ',1,2,'

Хорошая идея отфильтровать пробелы до и послезапятая годов.:)

0 голосов
/ 16 июля 2010

Попробуйте:

(Id IN (SELECT n FROM @ids) OR NOT EXISTS (SELECT * FROM @ids))
0 голосов
/ 16 июля 2010

Вы можете попробовать:

NOT EXISTS (SELECT 1 FROM @ids)
OR EXISTS (SELECT 1 FROM @ids where n = Id) 

Но лучше это небольшие таблицы - этот запрос, вероятно, не очень хорошо будет работать с любыми индексами на ваших таблицах.

...