2010-12-17 23 views
2

当执行以下存储过程时,我得到无效的对象名称dbo.Approved。对象dbo.Approved确实存在,所以大概这是与我传递表名作为参数的方式有关吗?无效的对象名称 - SQL服务器2005

我还应该补充一点,我通过.NET执行程序或从SMSS内部执行程序来获得错误。

@tableName as nvarchar(100) 
AS 
BEGIN 

EXEC(' 

UPDATE T1 
SET T1.NPTid = dbo.Locations.NPT_ID 
FROM ' + '[' + @tableName + '] As T1 
INNER JOIN dbo.Locations ON T1.Where_Committed = dbo.Locations.Location_Name 
') 

END 

编辑从乔和JNK接到求救后,现在的存储过程是这样的,但我得到的错误

Msg 102, Level 15, State 1, Procedure sp_Updater, Line 14 

Incorrect syntax near 'QUOTENAME'. 

新的存储过程

@tableName as nvarchar(100), 
@schemaName as nvarchar(20) 
AS 
BEGIN 



EXEC(' 
--Update NPT 
UPDATE T1 
SET T1.NPTid = dbo.Locations.NPT_ID 
FROM ' + QUOTENAME(@schemaName) + '.' + QUOTENAME(@tableName) + ' As T1 
INNER JOIN dbo.Locations ON T1.Where_Committed = dbo.Locations.Location_Name 
') 

END 
+0

你是如何将表名作为参数传递的? “dbo.Approved”或“Approved” – Ramy 2010-12-17 16:38:41

+0

是的,您可以忽略Alter Proc位 – MrBliz 2010-12-17 16:39:41

回答

5

用方括号在你的字符串,你表引用变成[dbo.Approved],这是无效的。改为参考应该是[dbo].[Approved]

您可能需要考虑将模式名称和表名称作为两个单独的参数传递。

使用QUOTENAME函数代替硬编码方括号也会更好。

declare @sql nvarchar(1000) 

set @sql = N'UPDATE T1 
SET T1.NPTid = dbo.Locations.NPT_ID 
FROM ' + QUOTENAME(@schemaName) + N'.' + QUOTENAME(@tableName) + N' As T1 
INNER JOIN dbo.Locations ON T1.Where_Committed = dbo.Locations.Location_Name 
' 

EXEC (@sql) 
+0

+1作为'QUOTENAME' – JNK 2010-12-17 16:41:01

+0

是这样的吗? FROM [dbo]。'+ QUOTENAME(@tableName)+']作为T1 – MrBliz 2010-12-17 16:46:15

+0

@Doozer - 在'AS T1'之前不需要右括号' – JNK 2010-12-17 16:46:45

2

你的包裹ID太早所以 '[' + @tablename +“]越来越被翻译成[dbo.approved]当它应该是[DBO]。[批准]

1

表名和列名实际上是sysname(这是因为我记得NVARCHAR(128)NVARCHAR(256) - 关闭我的头顶我不太记得)

此外,您很容易受到SQL注入攻击。您应该验证@tableName是一个真正的表通过检查其对INFORMATION_SCHEMA.TABLES

最后,只是为了绝对确保,万一真表中有一些奇怪的字符,你应该使用QUOTENAME(@tableName)完全逃脱表名。

+1

括号是问题,而不是数据类型:) – JNK 2010-12-17 16:42:59

+0

干杯。我知道它很容易受到SQL注入攻击,但它只是一个帮助器应用程序,只能在一台机器上运行,而我自己。 – MrBliz 2010-12-17 16:48:16

4

如果您使用的三部分名称括号,你需要有大约每节括号,但不是时期,即:

[dbo].[Approved]

如果传递dbo.Approved为您的参数,您的动态SQL正在将它读为[dbo.Approved],只有当您有一个名为该表的表(即dbo。是表名称的一部分而不是架构)时才会起作用。

将其更改为:

'...[dbo].[' + @tablename + ']...

而只是通过Approved作为参数。