Использование ISNULL (MAX (@Variable) возвращает переменную, а не число c, как ожидалось - PullRequest
0 голосов
/ 25 марта 2020

У меня запущена хранимая процедура, которая ищет имя ID в таблице переменных (v) как сводку других таблиц базы данных (a, b, c et c.). Поскольку не все таблицы имеют идентификатор с именем ID, я сохранил их в этой таблице переменных.

Это должно использоваться для получения максимального идентификатора из соответствующей таблицы.

При выполнении следующей команды все хорошо, и я получаю максимальный идентификатор для соответствующей таблицы:

DECLARE @TableMaxID INT

SELECT @TableMaxID  = ISNULL(MAX(TableID_a),0) 
FROM DB.SCHEMA.Table_a

PRINT @TableMaxID 

Запустив этот запрос, я правильно получаю таблицу формы максимального идентификатора a - '59'

Поскольку я хочу использовать переменную в этой команде я попробовал следующее

DECLARE @TableMaxID INT
    ,@TableIdName NVARCHAR (50)
SET @TableIdName = 'TableID_a'

SELECT TableMaxID  = ISNULL(MAX(@TableIdName),0) 
FROM DB.SCHEMA.Table_a

Выполнение этого вызывает ошибку

Преобразование не удалось при преобразовании значения nvarchar 'TableID_a' в тип данных int.

Когда я использую только команду SELECT, я понимаю, что происходит, - вместо имени цифры c '59'

DECLARE @TableMaxID INT
        ,@TableIdName NVARCHAR (50)
SET @TableIdName = 'TableID_a'

SELECT ISNULL(MAX(@TableIdName),0) 
FROM DB.SCHEMA.Table_a

PRINT @TableMaxID
* 1023 я получаю имя переменной @TableIdName * Возвращает имя переменной 'TableID_a'

Я немного запутался. Что я тут не так делаю. Есть ли способ использовать переменную, как я пытаюсь или я получаю что-то совершенно неправильно.

Ответы [ 2 ]

0 голосов
/ 25 марта 2020

Если вы используете переменную в выражении, ее значение будет использоваться в выражении, а не значение объекта, идентификатор которого равен значению переменной.

Похоже, вы хотите dynamici c SQL, т. Е. Создать текст запроса в переменной и затем выполнить этот запрос.

DECLARE @maxid integer;
DECLARE @idcolumnname sysname = 'di';
DECLARE @query nvarchar(max) = N'
SELECT @maxid = isnull(max(' + quotename(@idcolumnname) + N'), 0)
       FROM elbat;';

EXECUTE sp_executesql @query, N'@maxid integer output', @maxid = @maxid output;

SELECT @maxid;

db <> fiddle

Некоторые замечания, на которые следует обратить внимание:

  • Вы должны использовать sysname вместо некоторых [n][var]char для имен объектов. sysname специальный тип данных в явном виде для имен объектов.
  • Вы должны использовать quotename() в именах объектов, прежде чем объединять их с запросом, чтобы убедиться, что они правильно указаны в запросе. В противном случае возможны ошибки или даже возможность SQL инъекций.
0 голосов
/ 25 марта 2020

Если вы поместите строку в качестве параметра в функцию MAX, вы получите строку обратно (а не максимальное значение столбца с тем же именем):

SELECT MAX('TableID_a') -- output TableID_a

Таким образом, вы должны использовать Dynami c SQL оператор, чтобы создать оператор SQL и выполнить. Вы можете использовать такую ​​хранимую процедуру, чтобы получить столбец maxmimum указанной таблицы c:

-- procedure to get the maximum value of a column of a specific table.
CREATE PROCEDURE GetMaxValue @tableName VARCHAR(100), @columnName VARCHAR(100)
AS
DECLARE @sql NVARCHAR(100)
SET @sql = 'SELECT MAX(' + @columnName + ') FROM ' + @tableName;

EXEC sp_executesql @sql

Вы можете вызвать созданную хранимую процедуру GetMaxValue следующим образом:

EXEC GetMaxValue '<name-of-table>', '<name-of-column>'

Но имейте в виду, что этот вызов эквивалентен следующему SELECT утверждению:

SELECT MAX(<name-of-column>) FROM <name-of-table>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...