resueltos probabilidad muestrales mendenhall medicina introducción introduccion inferencial estadística estadistica ejercicios ejemplos distribuciones distribucion bioestadistica ala 13th .net sql sql-server tsql transactions

.net - probabilidad - Usar "IR" dentro de una transacción



introduccion ala probabilidad y estadistica mendenhall 13th pdf (8)

Estoy construyendo una aplicación web que intenta instalar / actualizar la base de datos en App_Start. Parte del procedimiento de instalación es garantizar que la base de datos tenga instaladas las características de asp.net. Para esto estoy usando el objeto System.Web.Management.SqlServices.

Mi intención es hacer todo el trabajo de la base de datos dentro de una transacción de SQL y si alguno falla, revertir la transacción y dejar la base de datos intacta.

el objeto SqlServices tiene un método "Install" que toma una ConnectionString pero no una transacción. Entonces, en su lugar, utilizo los SqlServices.GenerateApplicationServicesScripts de la siguiente manera:

string script = SqlServices.GenerateApplicationServicesScripts(true, SqlFeatures.All, _connection.Database); SqlHelper.ExecuteNonQuery(transaction, CommandType.Text, script, ...);

y luego uso el SqlHelper de Enterprise Library.

pero esto arroja una excepción con un montón de errores, algunos están por debajo

Incorrect syntax near ''GO''. Incorrect syntax near ''GO''. Incorrect syntax near ''GO''. Incorrect syntax near ''GO''. Incorrect syntax near the keyword ''USE''. Incorrect syntax near the keyword ''CREATE''. Incorrect syntax near ''GO''. The variable name ''@cmd'' has already been declared. Variable names must be unique within a query batch or stored procedure.

Supongo que es un problema utilizar la instrucción GO dentro de una Transacción SQL.

¿Cómo puedo hacer que este script generado funcione cuando se ejecuta de esta manera?


En realidad, puede usar declaraciones GO cuando usa las extensiones Microsoft.SqlServer.Management.Smo:

var script = GetScript(databaseName); var conn = new SqlConnection(connectionString.ConnectionString); var svrConnection = new ServerConnection(conn); var server = new Server(svrConnection); server.ConnectionContext.ExecuteNonQuery(script);

http://msdn.microsoft.com/de-de/library/microsoft.sqlserver.management.smo.aspx

Todo lo que necesita es los paquetes SQL CLR Types y SQL Management Objects implementados desde: http://www.microsoft.com/en-us/download/details.aspx?id=29065 (versión SQL 2012)


GO es un separador de lotes en SQL. Significa completar un lote completo. Por ejemplo, una variable definida en un batch @ID no se puede acceder después de la instrucción ''GO''. Por favor, consulte el siguiente código para la comprensión

Declare @ID nvarchar(5); set @ID = 5; select @ID GO select @ID


GO no es una palabra clave SQL.

Se trata de un separador por lotes utilizado por las herramientas del cliente (como SSMS) para dividir todo el script en lotes

Tendrá que dividir el script en lotes o usar algo como sqlcmd con "-c GO" o osql para tratar con "GO"


La manera del pobre de arreglar esto: dividir el SQL en las sentencias GO. Algo como:

private static List<string> getCommands(string testDataSql) { string[] splitcommands = File.ReadAllText(testDataSql).Split(new string[]{"GO/r/n"}, StringSplitOptions.RemoveEmptyEntries); List<string> commandList = new List<string>(splitcommands); return commandList; }

[eso fue realmente copiado de la aplicación en la que estoy trabajando ahora. Yo garun-freaking-tee este código]

Luego solo ExecuteNonQuery() sobre la lista. Obtenga lujo y use transacciones para obtener puntos de bonificación.

# # # # # PUNTOS EXTRA # # # # # #

Cómo manejar los bits de transacción realmente depende de los objetivos operativos. Básicamente puedes hacerlo de dos maneras:

a) Envuelva toda la ejecución en una sola transacción, lo que tendría sentido si realmente quisiera que todo se ejecutara o fallara (mejor opción en mi humilde opinión)

b) Envuelva cada llamada a ExecuteNonQuery() en su propia transacción. Bueno, en realidad, cada llamada es su propia transacción. Pero podría atrapar las excepciones y continuar con el próximo artículo. Por supuesto, si esto es típico de DDL generado, a menudo la siguiente parte depende de una parte previa, por lo que una falla parcial probablemente molestará a todo el perro.


Solo pensé en agregar mi solución aquí ... reemplazar el ''IR'' con un separador que ExecuteNonQuery entiende, es decir, el '';'' operador. Use esta función para corregir su script:

private static string FixGoDelimitedSqlScript(string script) { return script.Replace("/r/nGO/r/n", "/r/n;/r/n"); }

Puede no funcionar para T-SQL anidado complejo con '';'' operadores en ellos, pero funcionó para mí y mi guión. Hubiera usado el método de división mencionado anteriormente, pero estaba restringido por la biblioteca que estaba usando, así que tuve que encontrar otra solución. ¡Espero que esto ayude a alguien!

PD. Soy consciente de que el '';'' el operador es un separador de declaraciones y el operador ''IR'' es un separador de lotes, por lo que probablemente ningún script avanzado será arreglado.


Solo quiero agregar que si nombra su transacción, puede incluir varias secciones GO dentro y todas se retrotraerán como una unidad. Como:

BEGIN TRANSACTION TransactionWithGos; GO SET XACT_ABORT ON; -- Roll back everything if error occurs in script GO -- do stuff GO COMMIT TRANSACTION TransactionWithGos; GO


prueba tus scripts:

  • restaurar una copia de seguridad de producción en un servidor de copia de seguridad
  • ejecutar ejecutar secuencias de comandos con GO

instala tus scripts:

  • cerrar la aplicación
  • ir al modo de usuario único
  • Base de datos de respaldo
  • ejecutar scripts con GO, en caso de error restaurar copia de seguridad
  • volver al modo multiusuario
  • reiniciar aplicación

EDITAR como se indica a continuación, especifiqué tran donde el lote era realmente correcto.

El problema no es que no pueda usar GO dentro de una transacción sino que GO indique el final de un lote y no sea un comando T-SQL. Podría ejecutar todo el script usando SQLCMD, o dividirlo en GO y ejecutar cada lote por turno.