none
在应用程序中执行T-SQL RRS feed

  • 问题

  • use master

    go

    -- 第一部分T-SQL:
    if exists (select * from sysobjects where name = 'killspbydbname')     drop procedure killspbydbname

    -- 第二部分T-SQL:
    create procedure killSpByDbName
    @dbname varchar ( 20)
    as
    declare @sql nvarchar ( 500)
    declare @spid int                 
    set @sql = 'declare getspid cursor for select spid from sysprocesses where dbid=db_id(''' + @dbname + ''')'                          
    exec ( @sql )                  
    open getspid                      
    fetch next from getspid into @spid
    while @@fetch_status <> -1     
    begin
    exec ( 'kill ' + @spid )      
    fetch next from getspid into @spid
    end
    close getspid 
    deallocate getspid

    -- 第三部分T-SQL:
    exec killSpByDbName 'tempDataBase '    -- tempDataBase是待还原的数据库


    当在SQL Sever Query Analyser执行上述第一部分和第二部分T-SQL时,会出现这样的错误:'CREATE PROCEDURE' must be the first statement in a query batch.  而当在第一部分T-SQL和第二部分T-SQL之间使用GO的话,就可以正确执行。请问这是为什么。还有如果在C#程序中执行上述T-SQL的话,是不能使用GO的。当然,可以使用ExecuteNonQuery分别执行第一部分T-SQL和第二部分T-SQL,但是我希望能有另一种更好的方法,可以在应用程序中一次性执行上述第一部分T-SQL和第二部分T-SQL。        同样的情况也发生在第二部分T-SQL和第三部分T-SQL,当这两部T-SQL之间有GO时,不会出现问题,但当这两部分之间没有GO,且一次性执行这两部分T-SQL时,就会有这样的错误:Cannot add rows to sysdepends for the current stored procedure because it depends on the missing object 'killSpByDbName'. The stored procedure will still be created.

    请各位师兄指点!谢谢!


    Spark
    2011年4月3日 7:46

答案

  • go不是一个标准的t-sql语句, SQLCMD,OSQL或者SSMS会将go识别成batch结束的标志。

    加入你提交的语句中包含go:

    select 1
    go
    select 2
    
    
    这些工具将语句提交给服务器时并没有将go这个语句提交,而是将select 1 和select 2分两次提交。

    所以如果你的c#应用程序要提交大量的t-sql,需要人为的将各个sql区分出来.

    你同时提交了第二个语句和第三个语句,实际上第二个语句是创建存储过程的语句,他的作用范围是包含了第三个语句:这样就出现了一个逻辑错误(或者称之为递归),自己调用自己.

    你将第二和第三分开执行就可以了


    有dba的职位吗(北京的),请联系我 stswordman#hotmail.com
    • 已标记为答案 Ai-hua Qiu 2011年4月13日 7:59
    2011年4月5日 13:13
    版主

全部回复

  • 这个是by design。

    或者可以理解为 乌龟的屁股 --规定。

     


    family as water
    2011年4月3日 11:47
  • GO是批处理结束,从上一个GO到这个GO之间的SQL提交生成查询计划,这个过程只要有错误 编译就不进行;

    create语句必须是批的开始,这是规定,除非在过程体内

    第二个没GO时,当成嵌套了,所以会有那样的提示

     


    More: blog.csdn.net/happyflystone
    2011年4月3日 15:20
  • 第二个和第三个一块执行的话,是不是执行第三个的时候,第二个里面的存储过程此时尚未成功创建(也就是说,第二个里面要创建的存储过程只有等到全部的T-SQL都执行完了之后,它才真正的被创建,才可以被exec了),所以才会说:missing object 'killSpByDbName'.

    请问T-SQL可以调试吗?如何调试?  请指点!

    Yours reply is very appreciated!


    2011年4月4日 4:02
  • go不是一个标准的t-sql语句, SQLCMD,OSQL或者SSMS会将go识别成batch结束的标志。

    加入你提交的语句中包含go:

    select 1
    go
    select 2
    
    
    这些工具将语句提交给服务器时并没有将go这个语句提交,而是将select 1 和select 2分两次提交。

    所以如果你的c#应用程序要提交大量的t-sql,需要人为的将各个sql区分出来.

    你同时提交了第二个语句和第三个语句,实际上第二个语句是创建存储过程的语句,他的作用范围是包含了第三个语句:这样就出现了一个逻辑错误(或者称之为递归),自己调用自己.

    你将第二和第三分开执行就可以了


    有dba的职位吗(北京的),请联系我 stswordman#hotmail.com
    • 已标记为答案 Ai-hua Qiu 2011年4月13日 7:59
    2011年4月5日 13:13
    版主