2013-04-23 159 views
0

我正在使用ScriptDom解析SQL腳本。我的程序如下在嘗試使用TSql100Parser進行解析時無法正確解析sql腳本

static void Main(string[] args) 
     { 
      string script = @" 
          SET QUOTED_IDENTIFIER ON 
          GO 

          SET ANSI_NULLS ON 
          GO 

          CREATE PROCEDURE dbo.ws_Device_Update 
          (
           @ApplicationId uniqueidentifier , 
           @OriginalApplicationId uniqueidentifier , 
           @DeviceIMEI nvarchar (50) , 
           @OriginalDeviceIMEI nvarchar (50) , 
           @ModelId int , 
           @DeviceName nvarchar (50) , 
           @DeviceDescription nvarchar (255) , 
           @DeviceState int , 
           @IsExpired bit , 
           @IsSuspended bit , 
           @LastAccessed datetime , 
           @ClientSeqNo bigint , 
           @ServerSeqNo bigint , 
           @ModelCode varchar (50) , 
           @PushToken varchar (512) , 
           @PushLastAlive datetime , 
           @PushLastDead datetime , 
           @DeviceType int 
          ) 

          AS 

          UPDATE dbo.[ws_Device] 
          SET 

           [ModelId]    = @ModelId   --Does a device model change with same DeviceIMEI .I doubt it 
           ,[DeviceName]   = @DeviceName  --Does a device name change with same DeviceIMEI .I doubt it 
           ,[DeviceDescription] = @DeviceDescription --Does a device description change with same DeviceIMEI .I doubt it 
           ,[DeviceState]   = @DeviceState  
           ,[IsExpired]   = @IsExpired 
           ,[IsSuspended]   = @IsSuspended 
           ,[LastAccessed]   = @LastAccessed 
           ,[ClientSeqNo]   = @ClientSeqNo 
           ,[ServerSeqNo]   = @ServerSeqNo 
           ,[ModelCode]   = @ModelCode   --Does a device model code with same DeviceIMEI .I doubt it 
           ,[PushToken]   = @PushToken 
           ,[PushLastAlive]  = @PushLastAlive 
           ,[PushLastDead]   = @PushLastDead 
           ,[DeviceType]   = @DeviceType  --Does a device device type change with same DeviceIMEI .I doubt it 
          WHERE 
           [ApplicationId]   = @OriginalApplicationId 
          AND [DeviceIMEI]   = @OriginalDeviceIMEI 
          "; 

      IList<ParseError> parseErrors; 
      TSql100Parser tsqlParser = new TSql100Parser(false); 
      TSqlFragment fragment; 
      using (StringReader stringReader = new StringReader(script)) 
      { 
       fragment = (TSqlFragment)tsqlParser.Parse(stringReader, out parseErrors); 
      } 
      if (parseErrors.Count > 0) 
      { 
       Console.WriteLine(@"Errors encountered: ""{0}""", parseErrors[0].Message); 
      } 

      Console.ReadKey(); 
     } 

工作正常。

但是,如果我不提

SET QUOTED_IDENTIFIER ON 
GO 
SET ANSI_NULLS ON 
GO 

它未能

遇到錯誤: 「附近有語法錯誤創建」。

我的問題是,爲什麼它發生....沒有SET QUOTED_IDENTIFIER ONSET ANSI_NULLS ON,它仍然是一個有效的存儲過程。

或者是強制使用這些?有什麼辦法可以繞過嗎?

+0

*它仍然是一個有效的存儲過程* - 這些指令是服務器&不是存儲過程的一部分(它們在CREATE之外) – 2013-05-01 09:50:56

回答

1

普里問題是在CREATE PROCEDURE文本之前有一個(不可見的)0xFFFE。如果您使用鍵盤,則可以驗證這一點,轉到C字符並將光標移動到左側。你會發現在C的左邊光標看起來沒有前進到左邊,除非再次按下左箭頭鍵。

0xFFFE是用於檢測Unicode字節排序的字節順序標記,我懷疑它已經以某種方式進入您的代碼。現在,您可以使用DEL或BackSpace鍵簡單地刪除隱藏的字符,它會修復它。

同樣在將來總是要真正傳遞給TSql100Parser類的構造函數。帶引號的標識符處理默認爲ON,所以我們需要在解析器構造函數中尊重它。