복붙노트

[SQL] 트랜잭션 내에서 "GO"를 사용하여

SQL

트랜잭션 내에서 "GO"를 사용하여

나는 시도 / 설치 App_Start에서 데이터베이스를 업그레이드하는 웹 응용 프로그램을 짓고 있어요. 설치 절차의 일부는 데이터베이스가 설치된 asp.net 기능이 있는지 확인하는 것입니다. 이를 위해 나는 System.Web.Management.SqlServices 객체를 사용하고 있습니다.

내 의도는 SQL 트랜잭션 내에서 모든 데이터베이스 작업을 수행하는 것입니다 그것의 어떤 롤 다시 트랜잭션을 실패하고 그대로 데이터베이스를 떠날 경우.

SqlServices 객체는 트랜잭션을 ConnectionString을 소요하지만 방법 "설치"를 가지고있다. 그래서 그 대신 나는과 같이 SqlServices.GenerateApplicationServicesScripts을 사용합니다 :

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

그리고 나는 엔터프라이즈 라이브러리에서 SqlHelper를 사용합니다.

그러나이 오류의 엉덩이 - 부하 예외를 throw, 몇은 다음과 같습니다

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.

나는 그것이 SQL 트랜잭션 내에서 GO 문을 사용하여 몇 가지 문제입니다 추정하고있다.

이 방법으로 실행될 때 작업이 생성 된 스크립트를 얻을 수있는 방법.

해결법

  1. ==============================

    1.GO는 SQL 키워드 없습니다.

    GO는 SQL 키워드 없습니다.

    그것은 배치에 전체 스크립트를 깰 수 (SSMS 같은) 클라이언트 도구에 의해 사용되는 일괄 분리입니다

    당신은 "GO"를 다루는 "-c GO"또는 OSQL과 함께 SQLCMD 같은 자신이나 사용 무언가 배치에 스크립트를 중단해야합니다

  2. ==============================

    2.난 그냥 당신이 당신의 거래를 이름을 경우, 당신이 내에서 여러 GO 섹션을 포함 할 수 있음을 추가 할 수 있으며 단위로 모든 롤 다시는 것이다. 예를 들면 :

    난 그냥 당신이 당신의 거래를 이름을 경우, 당신이 내에서 여러 GO 섹션을 포함 할 수 있음을 추가 할 수 있으며 단위로 모든 롤 다시는 것이다. 예를 들면 :

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

    3.가난한 사람의 방법은이 문제를 해결하려면 다음 GO 문에 SQL을 분할합니다. 뭔가 같은 :

    가난한 사람의 방법은이 문제를 해결하려면 다음 GO 문에 SQL을 분할합니다. 뭔가 같은 :

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

    [그 사실 지금 작업하고있는 응용 프로그램 밖으로 복사되었습니다. 내가-괴물 garun - 티 코드]

    그런 다음 목록을 통해 단지 ExecuteNonQuery는 (). 보너스 포인트 공상 및 사용에 거래를 가져옵니다.

    어떻게 트랜잭션 비트를 처리하는 것은 정말 운영 목표에 따라 달라집니다. 기본적으로 당신은 두 가지 방법으로 할 수 있습니다 :

    A)) 당신이 정말로 중 하나를 실행하거나 실패 (더 나은 옵션 이럴 모든 것을 원한다면 이해 것이다, 단일 트랜잭션에서 전체 실행을 감싸

    b)는 자신의 거래에서 ExecuteNonQuery는 각 호출 ()를 감싸. 음, 사실, 각각의 호출은 자신의 거래이다. 하지만 당신은 예외를 포착하고 다음 항목으로 수행 할 수 있습니다. 이 일반적인 생성 된 DDL 물건 인 경우 물론, 자주 다음 부분은 한 부분 실패 때문에 이전 부분에 따라 달라집니다 것입니다 아마 전체 응가 놈.

  4. ==============================

    4.배치가 실제로 정확했다 어디 아래 뾰족한 아웃 등의 편집은 트란을 지정했습니다.

    배치가 실제로 정확했다 어디 아래 뾰족한 아웃 등의 편집은 트란을 지정했습니다.

    문제는 GO는 일괄 처리의 끝을 나타냅니다 당신이 너무 많은 트랜잭션 내에서 GO를 사용할 수 없습니다이며, T-SQL 명령 그 자체이다. 당신은 SQLCMD를 사용하여 전체 스크립트를 실행하거나, GO의에 분할 차례로 각 배치를 실행할 수 있습니다.

  5. ==============================

    5.GO는 SQL에 배치 구분자입니다. 그것은 하나 개의 전체 배치의 완성을 의미한다. 예를 들어, 하나의 배치 @ID에 정의 된 변수는 'GO'문 다음에 액세스 할 수 없습니다. 이해를 위해 아래의 코드를 참조하십시오

    GO는 SQL에 배치 구분자입니다. 그것은 하나 개의 전체 배치의 완성을 의미한다. 예를 들어, 하나의 배치 @ID에 정의 된 변수는 'GO'문 다음에 액세스 할 수 없습니다. 이해를 위해 아래의 코드를 참조하십시오

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

    6.스크립트를 테스트 :

    스크립트를 테스트 :

    스크립트를 설치합니다 :

  7. ==============================

    7.당신이 Microsoft.SqlServer.Management.Smo 확장을 사용할 때 사실, 당신은 GO 문을 사용할 수 있습니다 :

    당신이 Microsoft.SqlServer.Management.Smo 확장을 사용할 때 사실, 당신은 GO 문을 사용할 수 있습니다 :

        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

    당신이 필요로하는 모두는 SQL CLR 유형과 SQL 관리에서 배포 패키지를 객체 : http://www.microsoft.com/en-us/download/details.aspx?id=29065 (SQL 2012 버전)

  8. ==============================

    8.그냥 내가 ExecuteNonQuery는 이해하는 구분으로 'GO'를 대체 ... 여기 내 솔루션을 추가 할 거라고 생각 즉 ';' 운영자. 스크립트를 해결하기 위해이 기능을 사용합니다 :

    그냥 내가 ExecuteNonQuery는 이해하는 구분으로 'GO'를 대체 ... 여기 내 솔루션을 추가 할 거라고 생각 즉 ';' 운영자. 스크립트를 해결하기 위해이 기능을 사용합니다 :

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

    그것은 복잡한 중첩 된 T-SQL 작동하지 않을 수 있습니다 ';' 그들 사업자는하지만, 나와 내 스크립트했다. 나는 위에 나열된 분할 방법을 사용하는 것입니다,하지만 난 또 다른 해결 방법을 찾아야했다 그래서 내가 사용 된 라이브러리에 의해 제한되었다. 이 사람을 도움이되기를 바랍니다!

    추신. 나는 그 알고 있습니다 ';' 운영자는 성명 분리하고있는 고급 스크립트가 아마이 고정되지 않도록 'GO'연산자는 배치 분리합니다.

  9. from https://stackoverflow.com/questions/971177/using-go-within-a-transaction by cc-by-sa and MIT license