2016-04-04 3 views
2

у меня есть процедура:Почему я не могу создать таблицу с этим динамическим SQL?

ALTER PROCEDURE SP_CREATETABLE 
(
    @newTableName NVARCHAR(200) 
) 
AS 
BEGIN 
    DECLARE @sql NVARCHAR(MAX) 
    SELECT @sql = 'create table @tableName (id int identity(1,1) primary key)' 
    PRINT @sql 
    EXEC sp_executesql @sql, N'@tableName nvarchar(200)', @newTableName 
END 

Когда я пытаюсь выполнить это:

EXEC SP_CREATETABLE 'NEWTABLENAME'; 

Я получаю эту ошибку:

Msg 102, Level 15, State 1, Line 12
Incorrect syntax near '@tableName'.

+1

Side Примечание: вы должны ** ** не использовать 'sp_' префикс для хранимых процедур. Microsoft [зарезервировала этот префикс для собственного использования (см. * Именование сохраненных процедур *)] (http://msdn.microsoft.com/en-us/library/ms190669%28v=sql.105%29.aspx) и вы рискуете столкнуться с именем когда-нибудь в будущем. [Это также плохо для производительности вашей хранимой процедуры] (http://www.sqlperformance.com/2012/10/t-sql-queries/sp_prefix). Лучше просто просто избегать 'sp_' и использовать что-то еще в качестве префикса - или никакого префикса вообще! –

ответ

4

Вам нужно что-то вроде этого:

ALTER PROCEDURE SP_CREATETABLE 
(
    @newTableName NVARCHAR(200) 
) 
AS 
BEGIN 
    DECLARE @sql NVARCHAR(MAX) 
    SELECT @sql = 'create table ' + QUOTENAME(@newTableName) + ' (id int identity(1,1) primary key)' 
    PRINT @sql 
    EXEC sp_executesql @sql 
END 

EXEC SP_CREATETABLE 'NEWTABLENAME'; 
+0

@Prdp Как избежать этого: 'EXEC SAIR_CREATETABLE 'NEWTABLENAME(); drop table NEWTABLENAME '; ' –

+2

Функция QUOTENAME должна смягчить это. – alextansc

1

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

Я часто подходить к этому с помощью REPLACE():

ALTER PROCEDURE SP_CREATETABLE (
    @newTableName NVARCHAR(200) 
) 
AS 
BEGIN 
    DECLARE @sql NVARCHAR(MAX); 
    SELECT @sql = 'create table @tableName (id int identity(1,1) primary key)'; 
    SELECT @sql = REPLACE(@sql, '@tableName', @newTableName); 
    PRINT @sql; 
    EXEC sp_executesql @sql; 
END;