Динамический SQL (передача имени таблицы в качестве параметра)

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

например:

@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.

Ответ 1

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

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

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

Ответ 2

Вам нужно будет сделать это вот так: exec('select * from '[email protected]+' where...')

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

Ответ 3

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

Exec('SELECT * FROM ' + @tableName) 

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

Ответ 4

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

Ответ 5

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

Однако, глядя на SQL, вы имеете:

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

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

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

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