Хранимая процедура MSSQL выбирает все столбцы
У меня есть хранимая процедура, в которой инструкция SELECT выглядит так:
SELECT @KeyName FROM dbo.FiConfig WITH (NOLOCK) WHERE IssuerKey = @IssuerKey
Где я создаю его вот так:
CREATE PROCEDURE GET_FICONFIG @IssuerKey INT, @KeyName NVARCHAR(100)
Где KeyName
– это имя столбца, из которого я извлекаю свои данные.
Мой вопрос: можно ли передать *
для выбора всех столбцов, хотя процедура запрашивает конкретное имя столбца?
Редактировать: К сожалению, я думаю, что, возможно, неправильно сформулировал свой вопрос. Я искал способ проверить, может ли моя хранимая процедура определить, хочу ли я выбрать все записи из таблицы или только определенные столбцы из записи. Я решил свою проблему, используя некоторые проверки NULL и инструкции if / else.
Вы можете использовать динамический запрос:
CREATE PROCEDURE GET_FICONFIG @IssuerKey INT, @KeyName NVARCHAR(100) AS declare @s varchar(500) = 'SELECT ' + @KeyName + ' FROM dbo.FiConfig WITH (NOLOCK) WHERE IssuerKey = ' + CAST(@IssuerKey as VARCHAR(10)) exec(@s)
Вы должны быть осторожны. Возможная Sql Injection
. Но вы не можете передавать имена столбцов в качестве параметров для динамического запроса, так что другого пути нет.
Но вы можете выбрать из таблицы INFORMATION_SCHEMA.COLUMNS
чтобы убедиться, что правильное имя столбца прошло:
IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'FiConfig' AND COLUMN_NAME = @KeyName) BEGIN declare @s varchar(500) = 'SELECT ' + @KeyName + ' FROM dbo.FiConfig WITH (NOLOCK) WHERE IssuerKey = ' + CAST(@IssuerKey as VARCHAR(10)) exec(@s) END ELSE THROW...
РЕДАКТИРОВАТЬ:
Как пользователь @Lamak сказал, что лучше использовать QUOTENAME
. он автоматически добавит скобки вокруг значения переменной:
CREATE PROCEDURE GET_FICONFIG @IssuerKey INT, @KeyName NVARCHAR(100) AS declare @s varchar(500) = 'SELECT ' + QUOTENAME(@KeyName) + ' FROM dbo.FiConfig WITH (NOLOCK) WHERE IssuerKey = ' + CAST(@IssuerKey as VARCHAR(10)) exec(@s)
Попробуйте что-то вроде этого:
DECLARE @SqlCommand nvarchar(max) SELECT @SqlCommand = 'SELECT ' + @keyname + ' FROM dbo.FiConfig WITH (NOLOCK) WHERE IssuerKey = ' + cast(@IssuerKey as varchar(10)) EXEC sp_executeSQL @SqlCommand
Это позволит вам передать имя столбца или произвольное выражение (например, *
или агрегатную функцию, например sum()
),
Имейте в виду, что, поскольку это стоит, это опасно, поскольку проверка на @keyname отсутствует, поэтому он подвержен SQL-инъекции, если кто-то проходит, например, строку ''; DELETE FROM USERS; --
''; DELETE FROM USERS; --
''; DELETE FROM USERS; --
.
Однако вы можете параметризовать sp_executesql
чтобы уменьшить это; документация для этой хранимой процедуры находится здесь: https://msdn.microsoft.com/en-gb/library/ms188001.aspx
Однако параметризация sp_executesql
не позволит вам перейти в '*'
качестве аргумента в хранимую процедуру …