执行一个大的SQL脚本(使用GO命令)

我需要从C#程序中执行一大组SQL语句(创build一堆表,视图和存储过程)。

这些语句需要用GO语句分隔,但SqlCommand.ExecuteNonQuery()不喜欢GO语句。 我想我会发布的解决scheme作为参考,是分割GO行上的SQLstring,并分别执行每个批处理。

有更简单/更好的方法吗?

使用了解GO分隔符的SQL Serverpipe理对象(SMO)。 在这里看我的博客文章: http: //weblogs.asp.net/jongalloway/Handling-_2200_GO_2200_-Separators-in-SQL-Scripts- 2D00the -easy-way

示例代码:

 public static void Main() { string scriptDirectory = "c:\\temp\\sqltest\\"; string sqlConnectionString = "Integrated Security=SSPI;" + "Persist Security Info=True;Initial Catalog=Northwind;Data Source=(local)"; DirectoryInfo di = new DirectoryInfo(scriptDirectory); FileInfo[] rgFiles = di.GetFiles("*.sql"); foreach (FileInfo fi in rgFiles) { FileInfo fileInfo = new FileInfo(fi.FullName); string script = fileInfo.OpenText().ReadToEnd(); using (SqlConnection connection = new SqlConnection(sqlConnectionString)) { Server server = new Server(new ServerConnection(connection)); server.ConnectionContext.ExecuteNonQuery(script); } } } 

如果这样做对您不起作用,请参阅Phil Haack的库,它处理这个问题: http : //haacked.com/archive/2007/11/04/a-library-for-executing-sql-scripts-with-go-separators -and.aspx

这是我一起解决我眼前的问题。

 private void ExecuteBatchNonQuery(string sql, SqlConnection conn) { string sqlBatch = string.Empty; SqlCommand cmd = new SqlCommand(string.Empty, conn); conn.Open(); sql += "\nGO"; // make sure last batch is executed. try { foreach (string line in sql.Split(new string[2] { "\n", "\r" }, StringSplitOptions.RemoveEmptyEntries)) { if (line.ToUpperInvariant().Trim() == "GO") { cmd.CommandText = sqlBatch; cmd.ExecuteNonQuery(); sqlBatch = string.Empty; } else { sqlBatch += line + "\n"; } } } finally { conn.Close(); } } 

它需要GO命令在他们自己的行,并且不会检测块注释,所以这样的事情将被拆分,并导致一个错误:

 ExecuteBatchNonQuery(@" /* GO */", conn); 

您可以使用SQLpipe理对象来执行此操作。 这些是Management Studio用来执行查询的相同对象。 我相信Server.ConnectionContext.ExecuteNonQuery()将执行你所需要的。

“GO”批分隔符关键字实际上是由SQL Management Studio本身使用的,所以它知道在哪里终止它发送给服务器的批处理,而不是传递给SQL服务器。 如果您愿意,甚至可以在Management Studio中更改关键字。

基于Blorgbeard的解决scheme。

 foreach (var sqlBatch in commandText.Split(new[] { "GO" }, StringSplitOptions.RemoveEmptyEntries)) { sqlCommand.CommandText = sqlBatch; sqlCommand.ExecuteNonQuery(); } 

如果您不想使用SMO,例如因为您需要跨平台,则还可以使用SubText中的ScriptSplitter类。

这里是在C#和VB.NET中的实现

用法:

  string strSQL = @" SELECT * FROM INFORMATION_SCHEMA.columns GO SELECT * FROM INFORMATION_SCHEMA.views "; foreach(string Script in new Subtext.Scripting.ScriptSplitter(strSQL )) { Console.WriteLine(Script); } 

如果您在使用多行c样式的注释时遇到问题,请使用正则expression式删除注释:

 static string RemoveCstyleComments(string strInput) { string strPattern = @"/[*][\w\d\s]+[*]/"; //strPattern = @"/\*.*?\*/"; // Doesn't work //strPattern = "/\\*.*?\\*/"; // Doesn't work //strPattern = @"/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+/ "; // Doesn't work //strPattern = @"/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+/ "; // Doesn't work // http://stackoverflow.com/questions/462843/improving-fixing-a-regex-for-c-style-block-comments strPattern = @"/\*(?>(?:(?>[^*]+)|\*(?!/))*)\*/"; // Works ! string strOutput = System.Text.RegularExpressions.Regex.Replace(strInput, strPattern, string.Empty, System.Text.RegularExpressions.RegexOptions.Multiline); Console.WriteLine(strOutput); return strOutput; } // End Function RemoveCstyleComments 

删除单行注释在这里:

 https://stackoverflow.com/questions/9842991/regex-to-remove-single-line-sql-comments 

如果您不想安装SMO对象,则可以使用gplex工具(请参阅此答案 )

我也面临同样的问题,我找不到任何其他的方式,只是将单个SQL操作拆分为单独的文件,然后依次执行所有这些操作。

显然问题不在于DML命令列表,它们可以在没有GO之间执行; 与DDL不同的故事(创build,更改,删除…)

如果你不想走SMO路线,你可以search并replace“GO”作为“;” 和查询,你会。 请注意,最后的结果集将被返回。

我今天通过从一个文本文件加载我的SQL到一个string来完成这个。 然后,我使用string拆分function将string分隔成单独的命令,然后单独发送到服务器。 简单:)

刚刚意识到,你需要拆分\ nGO,以防万一你的表名出现在你的名字等。猜猜我在那里是幸运的!

如果你不想使用SMO(这比下面的解决scheme更好,但我想给出一个替代scheme…),你可以用这个function拆分你的查询。

它是:

  • 评论certificate(例如 – GO或/ * GO * /)
  • 只在一个新行上工作,就像在SSMS中一样(例如/ * test / * GO工作,select1作为不行
  • stringcertificate(例如打印“不行”)

     private List<string> SplitScriptGo(string script) { var result = new List<string>(); int pos1 = 0; int pos2 = 0; bool whiteSpace = true; bool emptyLine = true; bool inStr = false; bool inComment1 = false; bool inComment2 = false; while (true) { while (pos2 < script.Length && Char.IsWhiteSpace(script[pos2])) { if (script[pos2] == '\r' || script[pos2] == '\n') { emptyLine = true; inComment1 = false; } pos2++; } if (pos2 == script.Length) break; bool min2 = (pos2 + 1) < script.Length; bool min3 = (pos2 + 2) < script.Length; if (!inStr && !inComment2 && min2 && script.Substring(pos2, 2) == "--") inComment1 = true; if (!inStr && !inComment1 && min2 && script.Substring(pos2, 2) == "/*") inComment2 = true; if (!inComment1 && !inComment2 && script[pos2] == '\'') inStr = !inStr; if (!inStr && !inComment1 && !inComment2 && emptyLine && (min2 && script.Substring(pos2, 2).ToLower() == "go") && (!min3 || char.IsWhiteSpace(script[pos2 + 2]) || script.Substring(pos2 + 2, 2) == "--" || script.Substring(pos2 + 2, 2) == "/*")) { if (!whiteSpace) result.Add(script.Substring(pos1, pos2 - pos1)); whiteSpace = true; emptyLine = false; pos2 += 2; pos1 = pos2; } else { pos2++; whiteSpace = false; if (!inComment2) emptyLine = false; } if (!inStr && inComment2 && pos2 > 1 && script.Substring(pos2 - 2, 2) == "*/") inComment2 = false; } if (!whiteSpace) result.Add(script.Substring(pos1)); return result; } 

使用以下方法拆分string并逐批执行

 using System; using System.IO; using System.Text.RegularExpressions; namespace RegExTrial { class Program { static void Main(string[] args) { string sql = String.Empty; string path=@"D:\temp\sample.sql"; using (StreamReader reader = new StreamReader(path)) { sql = reader.ReadToEnd(); } //Select any GO (ignore case) that starts with at least //one white space such as tab, space,new line, verticle tab etc string pattern="[\\s](?i)GO(?-i)"; Regex matcher = new Regex(pattern, RegexOptions.Compiled); int start = 0; int end = 0; Match batch=matcher.Match(sql); while (batch.Success) { end = batch.Index; string batchQuery = sql.Substring(start, end - start).Trim(); //execute the batch ExecuteBatch(batchQuery); start = end + batch.Length; batch = matcher.Match(sql,start); } } private static void ExecuteBatch(string command) { //execute your query here } } } 

我在java中有同样的问题,我用一些逻辑和正则expression式来解决它。 我相信可以应用同样的逻辑。首先我从slq文件读入内存。 然后我应用以下逻辑。 这是几乎所有以前说过的,但是我相信使用正则expression式绑定比期待一个新的行char更安全。

 String pattern = "\\bGO\\b|\\bgo\\b"; String[] splitedSql = sql.split(pattern); for (String chunk : splitedSql) { getJdbcTemplate().update(chunk); } 

这基本上把sqlstring分割成一个sqlstring数组。 正则expression式基本上是检测小写或大写的完整“去”字。 然后你依次执行不同的查询。

我遇到了同样的问题,最后只是用一个简单的stringreplace来解决它,用分号(;)代替GO。

所有似乎都正常工作,同时执行脚本与行内评论,块注释和GO命令

 public static bool ExecuteExternalScript(string filePath) { using (StreamReader file = new StreamReader(filePath)) using (SqlConnection conn = new SqlConnection(dbConnStr)) { StringBuilder sql = new StringBuilder(); string line; while ((line = file.ReadLine()) != null) { // replace GO with semi-colon if (line == "GO") sql.Append(";"); // remove inline comments else if (line.IndexOf("--") > -1) sql.AppendFormat(" {0} ", line.Split(new string[] { "--" }, StringSplitOptions.None)[0]); // just the line as it is else sql.AppendFormat(" {0} ", line); } conn.Open(); SqlCommand cmd = new SqlCommand(sql.ToString(), conn); cmd.ExecuteNonQuery(); } return true; } 

为了避免第三方,正则expression式,内存开销和大脚本的快速工作,我创build了自己的基于stream的parsing器。 它

  • 检查之前的语法
  • 可以用 – 或/ ** /

     -- some commented text /* drop table Users; GO */ 
  • 可以识别string与“或”

     set @s = 'create table foo(...); GO create index ...'; 
  • 保留LF和CR格式
  • 保留对象实体(存储过程,视图等)中的注释块
  • 和其他build筑如

      gO -- commented text 

如何使用

  try { using (SqlConnection connection = new SqlConnection("Integrated Security=SSPI;Persist Security Info=True;Initial Catalog=DATABASE-NAME;Data Source=SERVER-NAME")) { connection.Open(); int rowsAffected = SqlStatementReader.ExecuteSqlFile( "C:\\target-sql-script.sql", connection, // Don't forget to use the correct file encoding!!! Encoding.Default, // Indefinitely (sec) 0 ); } } // implement your handlers catch (SqlStatementReader.SqlBadSyntaxException) { } catch (SqlException) { } catch (Exception) { } 

基于stream的SQL脚本阅读器

 class SqlStatementReader { public class SqlBadSyntaxException : Exception { public SqlBadSyntaxException(string description) : base(description) { } public SqlBadSyntaxException(string description, int line) : base(OnBase(description, line, null)) { } public SqlBadSyntaxException(string description, int line, string filePath) : base(OnBase(description, line, filePath)) { } private static string OnBase(string description, int line, string filePath) { if (filePath == null) return string.Format("Line: {0}. {1}", line, description); else return string.Format("File: {0}\r\nLine: {1}. {2}", filePath, line, description); } } enum SqlScriptChunkTypes { InstructionOrUnquotedIdentifier = 0, BracketIdentifier = 1, QuotIdentifierOrLiteral = 2, DblQuotIdentifierOrLiteral = 3, CommentLine = 4, CommentMultiline = 5, } StreamReader _sr = null; string _filePath = null; int _lineStart = 1; int _lineEnd = 1; bool _isNextChar = false; char _nextChar = '\0'; public SqlStatementReader(StreamReader sr) { if (sr == null) throw new ArgumentNullException("StreamReader can't be null."); if (sr.BaseStream is FileStream) _filePath = ((FileStream)sr.BaseStream).Name; _sr = sr; } public SqlStatementReader(StreamReader sr, string filePath) { if (sr == null) throw new ArgumentNullException("StreamReader can't be null."); _sr = sr; _filePath = filePath; } public int LineStart { get { return _lineStart; } } public int LineEnd { get { return _lineEnd == 1 ? _lineEnd : _lineEnd - 1; } } public void LightSyntaxCheck() { while (ReadStatementInternal(true) != null) ; } public string ReadStatement() { for (string s = ReadStatementInternal(false); s != null; s = ReadStatementInternal(false)) { // skip empty for (int i = 0; i < s.Length; i++) { switch (s[i]) { case ' ': continue; case '\t': continue; case '\r': continue; case '\n': continue; default: return s; } } } return null; } string ReadStatementInternal(bool syntaxCheck) { if (_isNextChar == false && _sr.EndOfStream) return null; StringBuilder allLines = new StringBuilder(); StringBuilder line = new StringBuilder(); SqlScriptChunkTypes nextChunk = SqlScriptChunkTypes.InstructionOrUnquotedIdentifier; SqlScriptChunkTypes currentChunk = SqlScriptChunkTypes.InstructionOrUnquotedIdentifier; char ch = '\0'; int lineCounter = 0; int nextLine = 0; int currentLine = 0; bool nextCharHandled = false; bool foundGO; int go = 1; while (ReadChar(out ch)) { if (nextCharHandled == false) { currentChunk = nextChunk; currentLine = nextLine; switch (currentChunk) { case SqlScriptChunkTypes.InstructionOrUnquotedIdentifier: if (ch == '[') { currentChunk = nextChunk = SqlScriptChunkTypes.BracketIdentifier; currentLine = nextLine = lineCounter; } else if (ch == '"') { currentChunk = nextChunk = SqlScriptChunkTypes.DblQuotIdentifierOrLiteral; currentLine = nextLine = lineCounter; } else if (ch == '\'') { currentChunk = nextChunk = SqlScriptChunkTypes.QuotIdentifierOrLiteral; currentLine = nextLine = lineCounter; } else if (ch == '-' && (_isNextChar && _nextChar == '-')) { nextCharHandled = true; currentChunk = nextChunk = SqlScriptChunkTypes.CommentLine; currentLine = nextLine = lineCounter; } else if (ch == '/' && (_isNextChar && _nextChar == '*')) { nextCharHandled = true; currentChunk = nextChunk = SqlScriptChunkTypes.CommentMultiline; currentLine = nextLine = lineCounter; } else if (ch == ']') { throw new SqlBadSyntaxException("Incorrect syntax near ']'.", _lineEnd + lineCounter, _filePath); } else if (ch == '*' && (_isNextChar && _nextChar == '/')) { throw new SqlBadSyntaxException("Incorrect syntax near '*'.", _lineEnd + lineCounter, _filePath); } break; case SqlScriptChunkTypes.CommentLine: if (ch == '\r' && (_isNextChar && _nextChar == '\n')) { nextCharHandled = true; currentChunk = nextChunk = SqlScriptChunkTypes.InstructionOrUnquotedIdentifier; currentLine = nextLine = lineCounter; } else if (ch == '\n' || ch == '\r') { currentChunk = nextChunk = SqlScriptChunkTypes.InstructionOrUnquotedIdentifier; currentLine = nextLine = lineCounter; } break; case SqlScriptChunkTypes.CommentMultiline: if (ch == '*' && (_isNextChar && _nextChar == '/')) { nextCharHandled = true; nextChunk = SqlScriptChunkTypes.InstructionOrUnquotedIdentifier; nextLine = lineCounter; } else if (ch == '/' && (_isNextChar && _nextChar == '*')) { throw new SqlBadSyntaxException("Missing end comment mark '*/'.", _lineEnd + currentLine, _filePath); } break; case SqlScriptChunkTypes.BracketIdentifier: if (ch == ']') { nextChunk = SqlScriptChunkTypes.InstructionOrUnquotedIdentifier; nextLine = lineCounter; } break; case SqlScriptChunkTypes.DblQuotIdentifierOrLiteral: if (ch == '"') { if (_isNextChar && _nextChar == '"') { nextCharHandled = true; } else { nextChunk = SqlScriptChunkTypes.InstructionOrUnquotedIdentifier; nextLine = lineCounter; } } break; case SqlScriptChunkTypes.QuotIdentifierOrLiteral: if (ch == '\'') { if (_isNextChar && _nextChar == '\'') { nextCharHandled = true; } else { nextChunk = SqlScriptChunkTypes.InstructionOrUnquotedIdentifier; nextLine = lineCounter; } } break; } } else nextCharHandled = false; foundGO = false; if (currentChunk == SqlScriptChunkTypes.InstructionOrUnquotedIdentifier || go >= 5 || (go == 4 && currentChunk == SqlScriptChunkTypes.CommentLine)) { // go = 0 - break, 1 - begin of the string, 2 - spaces after begin of the string, 3 - G or g, 4 - O or o, 5 - spaces after GO, 6 - line comment after valid GO switch (go) { case 0: if (ch == '\r' || ch == '\n') go = 1; break; case 1: if (ch == ' ' || ch == '\t') go = 2; else if (ch == 'G' || ch == 'g') go = 3; else if (ch != '\n' && ch != '\r') go = 0; break; case 2: if (ch == 'G' || ch == 'g') go = 3; else if (ch == '\n' || ch == '\r') go = 1; else if (ch != ' ' && ch != '\t') go = 0; break; case 3: if (ch == 'O' || ch == 'o') go = 4; else if (ch == '\n' || ch == '\r') go = 1; else go = 0; break; case 4: if (ch == '\r' && (_isNextChar && _nextChar == '\n')) go = 5; else if (ch == '\n' || ch == '\r') foundGO = true; else if (ch == ' ' || ch == '\t') go = 5; else if (ch == '-' && (_isNextChar && _nextChar == '-')) go = 6; else go = 0; break; case 5: if (ch == '\r' && (_isNextChar && _nextChar == '\n')) go = 5; else if (ch == '\n' || ch == '\r') foundGO = true; else if (ch == '-' && (_isNextChar && _nextChar == '-')) go = 6; else if (ch != ' ' && ch != '\t') throw new SqlBadSyntaxException("Incorrect syntax was encountered while parsing go.", _lineEnd + lineCounter, _filePath); break; case 6: if (ch == '\r' && (_isNextChar && _nextChar == '\n')) go = 6; else if (ch == '\n' || ch == '\r') foundGO = true; break; default: go = 0; break; } } else go = 0; if (foundGO) { if (ch == '\r' || ch == '\n') { ++lineCounter; } // clear GO string s = line.Append(ch).ToString(); for (int i = 0; i < s.Length; i++) { switch (s[i]) { case ' ': continue; case '\t': continue; case '\r': continue; case '\n': continue; default: _lineStart = _lineEnd; _lineEnd += lineCounter; return allLines.Append(s.Substring(0, i)).ToString(); } } return string.Empty; } // accumulate by string if (ch == '\r' && (_isNextChar == false || _nextChar != '\n')) { ++lineCounter; if (syntaxCheck == false) allLines.Append(line.Append('\r').ToString()); line.Clear(); } else if (ch == '\n') { ++lineCounter; if (syntaxCheck == false) allLines.Append(line.Append('\n').ToString()); line.Clear(); } else { if (syntaxCheck == false) line.Append(ch); } } // this is the end of the stream, return it without GO, if GO exists switch (currentChunk) { case SqlScriptChunkTypes.InstructionOrUnquotedIdentifier: case SqlScriptChunkTypes.CommentLine: break; case SqlScriptChunkTypes.CommentMultiline: if (nextChunk != SqlScriptChunkTypes.InstructionOrUnquotedIdentifier) throw new SqlBadSyntaxException("Missing end comment mark '*/'.", _lineEnd + currentLine, _filePath); break; case SqlScriptChunkTypes.BracketIdentifier: if (nextChunk != SqlScriptChunkTypes.InstructionOrUnquotedIdentifier) throw new SqlBadSyntaxException("Unclosed quotation mark [.", _lineEnd + currentLine, _filePath); break; case SqlScriptChunkTypes.DblQuotIdentifierOrLiteral: if (nextChunk != SqlScriptChunkTypes.InstructionOrUnquotedIdentifier) throw new SqlBadSyntaxException("Unclosed quotation mark \".", _lineEnd + currentLine, _filePath); break; case SqlScriptChunkTypes.QuotIdentifierOrLiteral: if (nextChunk != SqlScriptChunkTypes.InstructionOrUnquotedIdentifier) throw new SqlBadSyntaxException("Unclosed quotation mark '.", _lineEnd + currentLine, _filePath); break; } if (go >= 4) { string s = line.ToString(); for (int i = 0; i < s.Length; i++) { switch (s[i]) { case ' ': continue; case '\t': continue; case '\r': continue; case '\n': continue; default: _lineStart = _lineEnd; _lineEnd += lineCounter + 1; return allLines.Append(s.Substring(0, i)).ToString(); } } } _lineStart = _lineEnd; _lineEnd += lineCounter + 1; return allLines.Append(line.ToString()).ToString(); } bool ReadChar(out char ch) { if (_isNextChar) { ch = _nextChar; if (_sr.EndOfStream) _isNextChar = false; else _nextChar = Convert.ToChar(_sr.Read()); return true; } else if (_sr.EndOfStream == false) { ch = Convert.ToChar(_sr.Read()); if (_sr.EndOfStream == false) { _isNextChar = true; _nextChar = Convert.ToChar(_sr.Read()); } return true; } else { ch = '\0'; return false; } } public static int ExecuteSqlFile(string filePath, SqlConnection connection, Encoding fileEncoding, int commandTimeout) { int rowsAffected = 0; using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)) { // Simple syntax check (you can comment out these two lines below) new SqlStatementReader(new StreamReader(fs, fileEncoding)).LightSyntaxCheck(); fs.Seek(0L, SeekOrigin.Begin); // Read statements without GO SqlStatementReader rd = new SqlStatementReader(new StreamReader(fs, fileEncoding)); string stmt; while ((stmt = rd.ReadStatement()) != null) { using (SqlCommand cmd = connection.CreateCommand()) { cmd.CommandText = stmt; cmd.CommandTimeout = commandTimeout; int i = cmd.ExecuteNonQuery(); if (i > 0) rowsAffected += i; } } } return rowsAffected; } } 

太难了 :)

创build数组stringstr []用“,@”代替GO:

  string[] str ={ @" USE master; ",@" CREATE DATABASE " +con_str_initdir+ @"; ",@" -- Verify the database files and sizes --SELECT name, size, size*1.0/128 AS [Size in MBs] --SELECT name --FROM sys.master_files --WHERE name = N'" + con_str_initdir + @"'; --GO USE " + con_str_initdir + @"; ",@" SET ANSI_NULLS ON ",@" SET QUOTED_IDENTIFIER ON ",@" IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Customers]') AND type in (N'U')) BEGIN CREATE TABLE [dbo].[Customers]( [CustomerID] [int] IDENTITY(1,1) NOT NULL, [CustomerName] [nvarchar](50) NULL, CONSTRAINT [PK_Customers] PRIMARY KEY CLUSTERED ( [CustomerID] ASC )WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY] ) ON [PRIMARY] END ",@" SET ANSI_NULLS ON ",@" SET QUOTED_IDENTIFIER ON ",@" IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[GOODS]') AND type in (N'U')) BEGIN CREATE TABLE [dbo].[GOODS]( [GoodsID] [int] IDENTITY(1,1) NOT NULL, [GoodsName] [nvarchar](50) NOT NULL, [GoodsPrice] [float] NOT NULL, CONSTRAINT [PK_GOODS] PRIMARY KEY CLUSTERED ( [GoodsID] ASC )WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY] ) ON [PRIMARY] END ",@" SET ANSI_NULLS ON ",@" SET QUOTED_IDENTIFIER ON ",@" IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Orders]') AND type in (N'U')) BEGIN CREATE TABLE [dbo].[Orders]( [OrderID] [int] IDENTITY(1,1) NOT NULL, [CustomerID] [int] NOT NULL, [Date] [smalldatetime] NOT NULL, CONSTRAINT [PK_Orders] PRIMARY KEY CLUSTERED ( [OrderID] ASC )WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY] ) ON [PRIMARY] END ",@" SET ANSI_NULLS ON ",@" SET QUOTED_IDENTIFIER ON ",@" IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[OrderDetails]') AND type in (N'U')) BEGIN CREATE TABLE [dbo].[OrderDetails]( [OrderID] [int] NOT NULL, [GoodsID] [int] NOT NULL, [Qty] [int] NOT NULL, [Price] [float] NOT NULL, CONSTRAINT [PK_OrderDetails] PRIMARY KEY CLUSTERED ( [OrderID] ASC, [GoodsID] ASC )WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY] ) ON [PRIMARY] END ",@" SET ANSI_NULLS ON ",@" SET QUOTED_IDENTIFIER ON ",@" IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[InsertCustomers]') 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].[InsertCustomers] @CustomerName nvarchar(50), @Identity int OUT AS INSERT INTO Customers (CustomerName) VALUES(@CustomerName) SET @Identity = SCOPE_IDENTITY() ' END ",@" IF NOT EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo].[FK_Orders_Customers]') AND parent_object_id = OBJECT_ID(N'[dbo].[Orders]')) ALTER TABLE [dbo].[Orders] WITH CHECK ADD CONSTRAINT [FK_Orders_Customers] FOREIGN KEY([CustomerID]) REFERENCES [dbo].[Customers] ([CustomerID]) ON UPDATE CASCADE ",@" ALTER TABLE [dbo].[Orders] CHECK CONSTRAINT [FK_Orders_Customers] ",@" IF NOT EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo].[FK_OrderDetails_GOODS]') AND parent_object_id = OBJECT_ID(N'[dbo].[OrderDetails]')) ALTER TABLE [dbo].[OrderDetails] WITH CHECK ADD CONSTRAINT [FK_OrderDetails_GOODS] FOREIGN KEY([GoodsID]) REFERENCES [dbo].[GOODS] ([GoodsID]) ON UPDATE CASCADE ",@" ALTER TABLE [dbo].[OrderDetails] CHECK CONSTRAINT [FK_OrderDetails_GOODS] ",@" IF NOT EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo].[FK_OrderDetails_Orders]') AND parent_object_id = OBJECT_ID(N'[dbo].[OrderDetails]')) ALTER TABLE [dbo].[OrderDetails] WITH CHECK ADD CONSTRAINT [FK_OrderDetails_Orders] FOREIGN KEY([OrderID]) REFERENCES [dbo].[Orders] ([OrderID]) ON UPDATE CASCADE ON DELETE CASCADE ",@" ALTER TABLE [dbo].[OrderDetails] CHECK CONSTRAINT [FK_OrderDetails_Orders] "}; for(int i =0; i<str.Length;i++) { myCommand.CommandText=str[i]; try { myCommand.ExecuteNonQuery(); } catch (SystemException ee) { MessageBox.Show("Error "+ee.ToString()); } } 

就这样,享受。