2016-04-04 76 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

旁註:你應該** **不使用'sp_'前綴爲您的存儲過程。微軟已經保留了這個前綴以供自己使用(參見*命名存儲過程*)](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; 
相關問題