0

我正在尝试半自动化创建我的数据库作为其中的一部分,我想添加列描述的扩展属性。当我尝试在我的脚本中运行 sp_sqlexec 时(甚至只是 Exec(@mystring) 我得到一个错误。但是,如果在调试时,我从监视窗口复制动态 sql 字符串,然后在复制的字符串上单独运行 sp_sqlexec窗口我没有得到任何错误并且扩展属性被正确添加。以下脚本演示了该问题:

--Create a table to apply column descriptions to 

Create table dbo.table1 (id int, name nvarchar(20));

--Create the table that contains our column descriptions

Create table dbo.column_descs_table (schemaname nvarchar(20), tablename nvarchar(20), columnname nvarchar(20), column_description nvarchar(20))

Insert into column_descs_table (schemaname, tablename, columnname, column_description)
values ('dbo', 'table1', 'id', 'the id column'), ('dbo' , 'table1', 'name', 'the name column');

--Dynamic sql string varaible to hold the commands
Declare @dyn_sql nvarchar(max);
Set @dyn_sql = 'N'''; --Set to opening quote 

--now create the string containing commands to add column escriptions
SELECT @dyn_sql = @dyn_sql + N' EXEC sp_addextendedproperty ''''Col Desc'''', ''''' + column_description + N''''', ''''SCHEMA'''', ' + schemaname +  N', ''''TABLE'''', ' + tablename + N', ''''COLUMN'''', ' + columnname + N' ;'   
FROM dbo.column_descs_table

Set @dyn_sql = @dyn_sql + ''''; --add the closing quote

Print @dyn_sql --If I copy the contents of @dyn_sql here and run seperately it works OK

Exec sp_sqlexec @dyn_sql -- this line causes error

我得到的错误是 Msg 102, Level 15, State 1, Line 1 Incorrect syntax near 'EXEC sp_addextendedproperty 'Col Desc', 'the id column', 'SCHEMA', dbo, 'TABLE', table1, 'COLUMN', id ; 执行 sp_addextendedprope'。

但是,如果我单步执行代码并复制 @dyn_sql 的内容,则将其粘贴如下:

exec sp_sqlexec N' EXEC sp_addextendedproperty ''Col Desc'', ''id 列'', ''SCHEMA'', dbo, ''TABLE'', table1, ''COLUMN'', id ; EXEC sp_addextendedproperty ''Col Desc'', ''名称列'', ''SCHEMA'', dbo, ''TABLE'', table1, ''COLUMN'', name ;'

然后上面的工作正常,列描述按预期添加。

非常感谢对此特定复制问题的任何帮助。我确实了解动态 sql 的安全问题(一旦我的设置完成,此脚本将从数据库中删除)

提前致谢

裘德

4

2 回答 2

0

我相信我已经解决了我的字符串复制问题。SQL 将连接字符串中的双引号检测为空字符串并将其删除。一个显示问题的简单示例和我的解决方案如下:

--Example to Select 'simple string' and then 'concat string' into results sets
DECLARE
   @Simplestring nvarchar( max ) = '' , 
   @Concatstring nvarchar( max ) = '' ,
   @Stringvar nvarchar( 10 ) = 'string';

--The double quotes in next line are the quotemark we want plus a quotemark acting 
--as an escape character
--@simplestring will be set to 'Select 'simple string' '
SET @Simplestring = 'Select ''simple string'' ';

--Similarly we need @concatstring to be set to 'Select 'Concat string' '
SET @Concatstring = 'Select  '' concat' + @Stringvar + ''; -- this wont work the last 
--double quote will be removed

--Add a character that cannot appear in any othe part of the concatenation - I've used *
SET @Concatstring = 'Select '' Concat ' + @Stringvar + '*';
--Now replace the * with a quote mark
SET @Concatstring = REPLACE( @Concatstring , '*' , '''' ); -- This will work

EXEC sp_executesql @Simplestring;  
EXEC sp_executesql @Concatstring;

可能有比我的更简单的解决方案。

非常感谢关于使用 sp_executesql 的建议。我正在更改我的代码以使用它(将变量作为参数传入)。

裘德

于 2012-05-18T13:11:57.157 回答
0

看起来这是因为您的前导 N 包含要执行的字符串中;你根本不需要它。换句话说,你最终会得到这样的结果:

exec sp_execsql 'N'' exec sp_addextendedproperty /* etc. */ '''

但它应该是这样的:

exec sp_execsql N'exec sp_addextendedproperty /* etc. */ '

但是你为什么还要在这里使用动态 SQL 呢?传递给 sp_addextendedproperty 的所有值都可以作为参数传递,因此没有明显的理由使用动态 SQL,除非您已针对问题进行了简化。

最后,您应该使用 sp_executesql,它是执行动态 SQL的首选方式。

于 2012-05-15T11:27:36.987 回答