Cursor执行t-sql创建视图语句

时间:2014-04-22 22:03:55

标签: sql sql-server cursor dynamic-sql

我希望将多个SQL视图从一个数据库迁移到另一个数据库。两个数据库定义都是相同的,因此我不必担心兼容性问题。我将不得不在几个客户端系统上执行此任务,所以我希望自动化它而不是使用'脚本视图为'选项并手动复制每个视图。

我对游标很陌生,所以如果这是一个非常简单的请求,我会道歉但是我已经尝试了几种方法并且无处可去。我对这个网站和其他网站的搜索同样毫无结果。这是我到目前为止所提出的:

declare @sql nvarchar(max)
declare @view nvarchar(max)
declare @dbname nvarchar(30)
set @dbname = 'DatabaseName'


DECLARE cCursor CURSOR LOCAL FOR
SELECT VIEW_DEFINITION 
from INFORMATION_SCHEMA.views
where TABLE_NAME like '%MyCriteria%'

OPEN cCursor
FETCH NEXT FROM cCursor into @view
        WHILE @@FETCH_STATUS = 0
    BEGIN
    set @sql  = 'USE ' + @dbname + ' GO ' + @view
    execute @sql
    FETCH NEXT FROM cCursor into @view
END
close cCursor
deallocate cCursor

我在执行时收到一条错误消息:     Msg 203,Level 16,State 2,Line 17     名称'使用DATA14 GO CREATE VIEW         ....不是有效的标识符。

其中....表示我从Information schema中获取的create view语句。

任何想法我做错了什么?

提前致谢。

编辑:

我尝试了另一种不依赖游标的方法,我相信我更接近,但我仍然遇到让我困惑的错误:

use SourceDB
go

declare @sql nvarchar(max)

set @sql = N''

select @sql = @sql + 'USE DestDB' + CHAR(13) + CHAR(10) + 'GO' + CHAR(13) + CHAR(10) +                         s.definition + CHAR(13) + CHAR(10) + 'GO' + CHAR(13) + CHAR(10) 
from sys.sql_modules as s
inner join sys.objects as o
on s.object_id = o.object_id
where o.type_desc = 'VIEW'
and s.definition like '%MyCriteria%'

exec data14..sp_executesql @sql
--select @sql

错误消息的文本是:     Msg 102,Level 15,State 1,Line 2     “' GO'附近的语法错误。     Msg 111,Level 15,State 1,Line 3     '创建视图'必须是查询批处理中的第一个语句。     Msg 102,Level 15,State 1,Line 22     GO' ......附近的语法不正确...... 等等列表中的每个视图

2 个答案:

答案 0 :(得分:0)

另一种选择是使用Powershell。有很多方法可以做到,我个人喜欢为每个脚本创建一个文件,我假设新数据库中不存在这些视图。所以这可能不会逐字逐句,但应该让你指出正确的方向。

  • 在服务器上创建导出文件夹(C:\ Temp \ Views)
  • 在对象资源管理器中打开源服务器。
  • 导航到源数据库(/ Databases / {DatabaseName})
  • 右键点击“视图”,然后选择“启动Powershell”
  • 运行以下命令,为每个视图创建一个文件:

    ls | ? { $_.name -match "MyCriteria" } | %{ $_.scriptheader(0) + $_.textbody > "C:\temp\views\$($_.Schema).$($_.name).sql" }

  • 使用

    将脚本导入另一个数据库

    ls "C:\temp\views" | %{ invoke-sqlcmd -inputfile $_.fullname -database "DatabaseName" }

答案 1 :(得分:0)

要实现您正在寻找的东西,您必须将动态SQL嵌套在动态SQL中......

DECLARE @sql nvarchar(max)
DECLARE @dbname nvarchar(30)
SET @dbname = 'DatabaseName'
SET @sql = '';

SELECT @sql = @sql + '
EXEC ' + @dbname + '.sys.sp_executesql N''' + REPLACE(VIEW_DEFINITION, '''', '''''') + ''''
FROM INFORMATION_SCHEMA.views
WHERE TABLE_NAME like '%table%'

EXEC (@sql);

虽然有一个问题。 双动态sql需要双重转义。因此上面的REPLACE。

顺便说一句......执行动态SQL的正确语法是EXEC(@SQL) - 注意括号 如果没有括号,您将告诉服务器执行一个过程。因此出现第一次错误的原因

希望有所帮助