2009-10-08 30 views
10

Tôi dường như không thể thực hiện SQL tạo cơ sở dữ liệu bằng cách sử dụng đối tượng DbCommand. Tôi đang làm gì sai? Dưới đây là mã của tôi:Làm thế nào để thực hiện SQL với các chú thích và câu lệnh GO sử dụng SqlConnection?

DbConnection connection; // initialized and opened elsewhere 
DbCommand cmd = connection.CreateCommand(); 
cmd.CommandText = sql; 
cmd.ExecuteNonQuery(); 

Dưới đây là các lỗi:

The query syntax is not valid., near term '/', line 1, column 2. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.Data.EntitySqlException: The query syntax is not valid., near term '/', line 1, column 2.

Dưới đây là phần đầu tiên của tập tin. Ngoại lệ được ném về chỉ các nhận xét trên dòng đầu tiên:

/****** Object: Table [dbo].[User] Script Date: 10/08/2009 12:14:29 ******/ 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
CREATE TABLE [dbo].[User](
    [Id] [int] IDENTITY(1,1) NOT NULL, 
    [FirstName] [nvarchar](50) NULL, 
    [LastName] [nvarchar](50) NULL, 
    [EmailAddress] [nvarchar](100) NULL, 
CONSTRAINT [PK_User] PRIMARY KEY CLUSTERED 
(
    [Id] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 
GO 

Kịch bản lệnh SQL này thực thi tốt với SQL Management Studio Express (trên thực tế ứng dụng đã tạo tập lệnh này!). Nó chỉ là khung nhìn truy vấn Server Explorer của Visual Studio và từ mã của riêng tôi mà dường như không thành công.

+1

Lưu ý: GO là không phải là một lệnh SQL, nó là một lệnh để các công cụ của khách hàng (ví dụ như OSQL, Query Analyzer, hoặc trong trường hợp này SMS.) Để phá vỡ kịch bản vào lô riêng biệt" ". Mỗi lô là một cuộc gọi riêng biệt đến máy chủ. –

+0

Có thể trùng lặp [Thực thi một tập lệnh SQL lớn (với lệnh GO)] (http://stackoverflow.com/questions/40814/execute-a-large-sql-script-with-go-commands) –

Trả lời

11

Bạn cần sử dụng các lớp quản lý SQL thay vì SqlCommand bình thường. This page shows you how to do it. Nếu bạn tự mình phân tích cú pháp SQL thì sẽ luôn có các trường hợp cạnh mà bạn bỏ lỡ. Ví dụ: nếu chuỗi trong mã chứa từ "GO" có trả về hàng đầu và đuôi sau?

Thêm những tài liệu tham khảo:

  • Microsoft.SqlServer.Smo
  • Microsoft.SqlServer.ConnectionInfo
  • Microsoft.SqlServer.Management.Sdk.Sfc (Edit: Tham chiếu này là không cần thiết)

Sau đó, bạn có thể sử dụng mã này:

string connectionString, scriptText; 
SqlConnection sqlConnection = new SqlConnection(connectionString); 
ServerConnection svrConnection = new ServerConnection(sqlConnection); 
Server server = new Server(svrConnection); 
server.ConnectionContext.ExecuteNonQuery(scriptText); 
+0

Tuyệt vời. Tôi không thể tìm thấy các 'Microsoft.SqlServer.Management.Sdk.Sfc' lắp ráp để tham khảo, nhưng nó bật ra nó không cần thiết anyway. –

8

Đây là một đoạn mã mà tôi posted on my blog một số thời gian trước đây mà có thể giải quyết vấn đề này:

private static void RunScript(SqlConnection connection, string script) 
{ 
    Regex regex = new Regex(@"\r{0,1}\nGO\r{0,1}\n"); 
    string[] commands = regex.Split(script); 

    for (int i = 0; i < commands.Length; i++) 
    { 
     if (commands[i] != string.Empty) 
     { 
      using(SqlCommand command = new SqlCommand(commands[i], connection)) 
      { 
       command.ExecuteNonQuery(); 
       command.Dispose(); 
      } 
     } 
    } 
} 

Nó chia tách các tập lệnh SQL vào các lệnh riêng biệt và thực hiện mỗi trong số họ. Tôi thường xuyên sử dụng điều này để thiết lập cơ sở dữ liệu thử nghiệm với các tập lệnh SQL được tạo.

+0

+1, nhưng Tôi không nghĩ đây là vấn đề _only_ ở đây. Lỗi này đang phàn nàn về nhận xét ở đầu tệp. –

+0

@ Jelel: Tôi nghĩ rằng nó * có thể * là nó thực sự phàn nàn về tuyên bố đầy đủ, điều này xảy ra để bắt đầu với nhận xét. Không thể chắc chắn mặc dù, vì vậy tôi đã chỉnh sửa văn bản để được ít nhất định trong việc liệu nó cung cấp một giải pháp hay không. –

+0

Máy chủ sê-ri GO có giá trị được surronded hợp lệ bởi khoảng trắng, ít nhất là trong SMSS cho SQL Server 2005. –

1

tôi thấy nó lạ mà bạn đang nhận được một EntitySqlException ...

Một giải pháp mà bạn có thể lựa chọn, là để thực hiện kịch bản này thông qua công cụ osql dòng lệnh. Bạn có thể tạo một cá thể System.Diagnostics.Process và sử dụng quá trình này để gọi osql để thực thi kịch bản.

System.Diagnostics.Process p = new System.Diagnostics.Process(); 

p.StartInfo.FileName = Environment.GetEnvironmentVariable ("COMSPEC"); 
p.StartInfo.UseShellExecute = false; 
p.StartInfo.ErrorDialog = false; 

p.StartInfo.CreateNoWindow = true; 
p.StartInfo.RedirectStandardInput = true; 
p.StartInfo.RedirectStandardError = true; 
p.StartInfo.RedirectStandardOutput = true; 

p.Start(); 

p.StandardInput.WriteLine ("echo off"); 
string command = @"osql -U -b -e -S " + servername + " -d " + databasename + " -i \'" + filename + "\'"; 
p.StandardInput.WriteLine (command); 
p.StandardInput.WriteLine ("exit"); 

p.WaitForExit(); 
+0

Cảm ơn mẹo. Điều này có thể hữu ích trong một kịch bản khác của tôi. –

0

trong SQL Server, bạn có thể nối nhiều truy vấn theo ý muốn với dấu tách cách đơn giản nhưng bạn cần xóa "GO".
dụ:

BEGIN TRANSACTION SET QUOTED_IDENTIFIER ON SET ARITHABORT ON SET NUMERIC_ROUNDABORT OFF SET CONCAT_NULL_YIELDS_NULL ON SET ANSI_NULLS ON SET ANSI_PADDING ON SET ANSI_WARNINGS ON COMMIT BEGIN TRANSACTION $remove this GO here$ CREATE TABLE dbo.Tmp_Tralala( ERRID numeric (18,0) NOT NULL)) ON [PRIMARY] $remove this GO here$ IF EXISTS(SELECT * FROM dbo.Tralala) EXEC('INSERT INTO ..etc 
Các vấn đề liên quan