2009-10-08 11 views
10

Parece que no puedo ejecutar SQL que crea una base de datos usando un objeto DbCommand. ¿Qué estoy haciendo mal? Aquí está mi código:¿Cómo ejecutar SQL con comentarios y declaraciones GO usando SqlConnection?

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

aquí es el error:

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.

Aquí está la primera parte del archivo. La excepción se produce con respecto a sólo los comentarios sobre la primera línea:

/****** 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 

Esta misma secuencia de comandos SQL se ejecuta muy bien desde SQL Management Studio Express (de hecho esa aplicación genera este guión!). Es solo la vista de consulta de Server Explorer de Visual Studio y de mi propio código que parece fallar.

+1

Nota: GO no es un comando SQL, es un comando para la herramienta de cliente (como OSQL, el analizador de consultas, o en este caso SMSS.) Para romper la secuencia de comandos en lotes separados" ". Cada lote es una llamada separada al servidor. –

+0

Posible duplicado de [Ejecutar un script SQL grande (con comandos GO)] (http://stackoverflow.com/questions/40814/execute-a-large-sql-script-with-go-commands) –

Respuesta

11

Necesita utilizar las clases de administración de SQL en lugar de la SqlCommand normal. This page shows you how to do it. Si intenta analizar el SQL usted mismo, siempre habrá casos límite que se pierda. Por ejemplo, ¿qué pasa si una cadena dentro del código contiene la palabra "IR" con retornos de carro anteriores y posteriores?

Añadir estas referencias:

  • Microsoft.SqlServer.Smo
  • Microsoft.SqlServer.ConnectionInfo
  • Microsoft.SqlServer.Management.Sdk.Sfc (Edit: ¿no necesita Esta referencia)

continuación, puede utilizar este código:

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

Awesome. No pude encontrar el ensamblado 'Microsoft.SqlServer.Management.Sdk.Sfc' como referencia, pero resultó que no era necesario de todos modos. –

8

Aquí es un fragmento de código que posted on my blog hace algún tiempo que puede resolver este problema:

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(); 
      } 
     } 
    } 
} 

divide la secuencia de comandos SQL en comandos separados y ejecuta cada uno de ellos. Regularmente uso esto para configurar bases de datos de prueba con scripts SQL generados.

+0

+1, pero No creo que este sea el único problema aquí. El error es quejarse del comentario en la parte superior del archivo. –

+0

@Joel: Creo que * puede * ser que en realidad se queja de la declaración completa, que comienza con el comentario. Sin embargo, no puedo estar seguro, así que he editado el texto para estar menos seguro de si proporciona una solución o no. –

+0

el separador de lotes GO es válido rodeado de espacios en blanco, al menos en SMSS para SQL Server 2005. –

1

Me parece extraño que usted está recibiendo un EntitySqlException ...

Otra solución que se puede elegir, es ejecutar esta secuencia de comandos a través de la herramienta osql de línea de comandos. Puede crear una instancia System.Diagnostics.Process y usar este proceso para llamar a osql, que a su vez ejecuta el script.

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

Gracias por el consejo. Esto puede ser útil en otro escenario mío. –

0

en SQL Server puede concatenar tantas consultas como desee con un simple separador de espacio, pero para eso se necesita para eliminar el "GO" s.
ejemplo:

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 
Cuestiones relacionadas