Динамический SQL (передача имени таблицы в качестве параметра) - PullRequest
12 голосов
/ 25 августа 2009

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

например:

@tablename << Parameter

SELECT * FROM @tablename

Как это возможно?

Я написал это:

set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[GetAllInterviewQuestions]
@Alias varchar = null
AS
BEGIN
Exec('Select * FROM Table as ' @Alias) 
END

Но он говорит неправильный синтаксис рядом с @ Alias.

Ответы [ 5 ]

19 голосов
/ 25 августа 2009

Ну, во-первых, вы пропустили '+' в вашей строке. Этот способ работы далек от идеала, но вы можете сделать

DECLARE @SQL varchar(250)
SELECT @SQL = 'SELECT * FROM ' + QuoteName(@Alias)
Exec(@SQL)

Однако я настоятельно рекомендую переосмыслить, как вы это делаете. Генерация динамического SQL часто приводит к уязвимостям SQL-инъекций, а также к тому, что SQL Server (и другим БД) становится все труднее найти лучший способ обработки вашего запроса. Если у вас есть хранимая процедура, которая может возвращать любую таблицу, вы на самом деле практически не получаете никакой выгоды от того, что она является хранимой процедурой, во-первых, поскольку она не сможет многое сделать на пути оптимизации в значительной степени лишает преимущества безопасности.

4 голосов
/ 25 августа 2009

Вы должны будете сделать это так: exec('select * from '+@tablename+' where...')

Но убедитесь, что вы полностью понимаете риски, такие как атаки с использованием SQL-инъекций. В общем, вам не нужно использовать что-то подобное, если БД хорошо спроектирована.

3 голосов
/ 25 августа 2009

Разве вы не имеете в виду

Exec('SELECT * FROM ' + @tableName) 

Кроме того, вы получаете ошибку, потому что вы забыли + до @ Alias.

1 голос
/ 25 августа 2009

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

0 голосов
/ 25 августа 2009

Большинство реализаций SQL не позволяют указывать структурные элементы - имена таблиц, имена столбцов, порядок по столбцам и т. Д. - через параметры; Вы должны использовать динамический SQL для параметризации этих аспектов запроса.

Однако, глядя на SQL, вы получаете:

Exec('SELECT * FROM Table AS ' @Alias)

Конечно, это будет означать, что код будет когда-либо выбираться только из таблицы с именем «Table», и вам нужно будет объединить @Alias ​​с ним - и на многих диалектах SQL конкатенация обозначается как «|| «:

Exec('SELECT * FROM Table AS ' || @Alias)

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...