【问题标题】:Error trying to execute SQL Server script file via ExecuteNonQuery on VB.NET尝试通过 VB.NET 上的 ExecuteNonQuery 执行 SQL Server 脚本文件时出错
【发布时间】:2013-12-13 23:59:50
【问题描述】:

该脚本在 SQL Management Studio 上运行良好,但在程序上却不行。脚本文件检查某些存储过程是否存在,如果存在则删除它们,然后再次声明它们,如下所示:

IF EXISTS(SELECT * FROM sys.objects WHERE type='P' AND name = 'myProc1')
  DROP PROCEDURE myProc1
GO
CREATE PROCEDURE myProc1
AS
BEGIN
  SELECT 
    [Field1] = ((*Some numeric value*)-(*Some numeric value*)),
    [Field2] = ((*Some numeric value*)-(*Some numeric value*)),
    [Field3] = ((*Some numeric value*)-(*Some numeric value*))
  FROM ...
  WHERE ...
END
GO

IF EXISTS(SELECT * FROM sys.objects WHERE type='P' AND name = 'myProc2')
  DROP PROCEDURE myProc2
GO
CREATE PROCEDURE myProc2
AS
BEGIN
  SELECT * FROM Table2
END
GO

IF EXISTS(SELECT * FROM sys.objects WHERE type='P' AND name = 'myProc3')
  DROP PROCEDURE myProc3
GO
CREATE PROCEDURE myProc3
AS
BEGIN
  SELECT * FROM Table3
END
GO

当我尝试在 VB.NET 上运行它时,我尝试了这个:

sql.CommandText = File.OpenText("C:\test.sql").ReadToEnd()
sql.CommandType = CommandType.Text
sql.Connection = connects.con
sql.ExecuteNonQuery()

我得到这个错误:

Incorrect syntax near 'GO'.
Incorrect syntax near 'GO'.
Incorrect syntax near 'GO'.
Incorrect syntax near ')'.
Incorrect syntax near '-'.
Incorrect syntax near ')'.
Incorrect syntax near '-'.
Incorrect syntax near ')'.
Incorrect syntax near '-'.
Incorrect syntax near '�'.

所以至少有 3 个 GO,3 个操作,甚至是一些未知字符。

关于我做错了什么有什么想法吗?

【问题讨论】:

    标签: sql vb.net sql-server-2008 stored-procedures


    【解决方案1】:

    我知道这是一个旧的,但我经常这样做,为了解决这个问题,我为 SQL Management Studio 中的存储过程生成脚本,并在高级下告诉它“检查对象是否存在”SQL 2010+(预2010 是检查对象是否存在或类似的东西)并将“Script DROP and CREATE”设置为“Script DROP and CREATE”。

    然后只需从脚本中取出“GO”(我通常将所有 GO 替换为空白并打开匹配案例,或者通过一键替换,因此我知道它是正确的 GO 被替换),然后它将在 VB.NET/t-SQL 中完美运行。

    这意味着它会生成这样的脚本:

    /****** Object:  StoredProcedure [dbo].[test3]    Script Date: 11/03/2015 16:47:48 ******/
    IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[test3]') AND type in (N'P', N'PC'))
    DROP PROCEDURE [dbo].[test3]
    
    /****** Object:  StoredProcedure [dbo].[test2]    Script Date: 11/03/2015 16:47:48 ******/
    IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[test2]') AND type in (N'P', N'PC'))
    DROP PROCEDURE [dbo].[test2]
    
    /****** Object:  StoredProcedure [dbo].[test1]    Script Date: 11/03/2015 16:47:48 ******/
    IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[test1]') AND type in (N'P', N'PC'))
    DROP PROCEDURE [dbo].[test1]
    
    /****** Object:  StoredProcedure [dbo].[test1]    Script Date: 11/03/2015 16:47:48 ******/
    SET ANSI_NULLS ON
    
    SET QUOTED_IDENTIFIER ON
    
    IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[test1]') AND type in (N'P', N'PC'))
    BEGIN
    EXEC dbo.sp_executesql @statement = N'-- =============================================
    -- Author:      <Author,,Name>
    -- Create date: <Create Date,,>
    -- Description: <Description,,>
    -- =============================================
    CREATE PROCEDURE [dbo].[test1]
    
    AS
    BEGIN
        print ''dummy procedure 1''
    END
    ' 
    END
    
    /****** Object:  StoredProcedure [dbo].[test2]    Script Date: 11/03/2015 16:47:48 ******/
    SET ANSI_NULLS ON
    
    SET QUOTED_IDENTIFIER ON
    
    IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[test2]') AND type in (N'P', N'PC'))
    BEGIN
    EXEC dbo.sp_executesql @statement = N'-- =============================================
    -- Author:      <Author,,Name>
    -- Create date: <Create Date,,>
    -- Description: <Description,,>
    -- =============================================
    CREATE PROCEDURE [dbo].[test2]
    
    AS
    BEGIN
        print ''dummy procedure 2''
    END
    ' 
    END
    
    /****** Object:  StoredProcedure [dbo].[test3]    Script Date: 11/03/2015 16:47:48 ******/
    SET ANSI_NULLS ON
    
    SET QUOTED_IDENTIFIER ON
    
    IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[test3]') AND type in (N'P', N'PC'))
    BEGIN
    EXEC dbo.sp_executesql @statement = N'-- =============================================
    -- Author:      <Author,,Name>
    -- Create date: <Create Date,,>
    -- Description: <Description,,>
    -- =============================================
    CREATE PROCEDURE [dbo].[test3]
    
    AS
    BEGIN
        print ''dummy procedure 3''
    END
    ' 
    END
    

    我大约在 5 年前开始这样做,从未遇到任何问题

    希望这对人们有所帮助

    问候

    利亚姆

    【讨论】:

      【解决方案2】:

      GO 命令是用于 SMSS 的 Batch separator,而不是 T-SQL 命令的一部分。然后,您的脚本将在 SSMS 中运行,因为它将执行每个批次。另一方面,.Net Framework 将脚本传递给底层 SQL 引擎,并将其视为一个大脚本,而不是分开的批次,这应该是你的错误。

      所以在一个命令中创建三个存储过程是行不通的。

      我的建议是您在后端单独创建脚本,然后您的 test.sql 应该如下所示:

        EXEC myProc1
        EXEC myProc2
        EXEC myProc3
      

      但是,如果您想动态创建三个存储过程,那么您可能只需将每个 CREATE PROCEDURE 分成三个不同的 sql 文本文件,即test1.sqltest2.sqltest3.sql for myProc1、@分别为987654331@和myProc3

      【讨论】:

      • 是的,虽然我并没有尝试执行它们,但我需要程序根据需要创建和“更新”它们,sql 脚本应该随着时间而改变,因此 SP 也会改变。而且我主要担心的是我可以在Management Studio中成功运行整个脚本,据我所知应该没有问题,因为每个SP都在一个特定的批次中,我知道它们不能一起声明。跨度>
      • .Net framework 获取脚本并立即将其传递给底层 SQL 引擎,而 Management Studio 分别使用每个 GO 语句解析脚本,因此您可以执行多个 CREATE PROCEDURE。请不要将SSMS.Net Framework 混淆。
      • GO 替代品吗?
      • 我认为您可以使用; 而不是GO,但如果您从程序中调用它,它仍然不起作用。无论如何,请参阅上面的更新答案。
      • 我理解你的回答,它确实有道理。问题是这个 sql 脚本的目的是让我们能够修改数据库中的存储过程,而无需更新程序本身(比如在添加新脚本时指定要执行的新脚本),而不仅仅是 sql。另外,如果我在一个 sql 脚本中声明每个 SP,我仍然必须在创​​建它们之前检查它们是否存在,因此脚本上不只有 SP。
      猜你喜欢
      • 2023-03-06
      • 2020-01-31
      • 2012-11-20
      • 2022-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-07
      相关资源
      最近更新 更多