Ошибка сгенерированной SQL для хранимых процедур, использующих SMO - PullRequest
0 голосов
/ 12 марта 2020

У нас есть приложение, которое создает легкие резервные копии больших баз данных SQL, чтобы наши сотрудники могли использовать их локально, а не загружать полную резервную копию объемом 75 ГБ и восстанавливать ее. В настоящее время приложение использует версию объекта Microsoft SMO 2012 года и работает нормально. Мы находимся в процессе развертывания этого в облаке AWS и используем NuGet для удаления пакета SMO, и это более новая версия SMO, и это вызывает у нас проблемы. Когда он создает сценарии для некоторых сохраненных процедур, синтаксис отличается, и когда пользователи запускают новый сценарий SMO, он выдает ошибку: «CREATE / ALTER PROCEDURE» должен быть первым оператором в пакете запроса ». Я искал, чтобы попытаться найти комбинацию параметров в параметрах SMO, чтобы увидеть, есть ли что-то, что могло бы решить эту проблему, и ни один из них, кажется, не может это исправить. Исследования показывают, что эта ошибка происходит из-за отсутствия оператора GO, но из-за того, что сгенерированный SQL настолько радикально отличается, а также из-за отсутствия документации об изменениях между версиями, я озадачен тем, как решить эту проблему.

SMO2012

SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[AUDITLOG].[CREATE_AUDITLOG_SECURITY_ENTRY]') AND type in (N'P', N'PC'))
BEGIN
EXEC dbo.sp_executesql @statement = N'/*====================================================================
Object:     AUDITLOG.CREATE_AUDITLOG_SECURITY_ENTRY
Desc:       Creates an audit entry into the AUDITLOG.AUDITLOG table and the AUDITLOG.AUDITLOG_SECURITY with the supplied data.
Parameters:
Name                          Optional  Description
      @AUDITAREA:             No,       The area being audited
      @USERID:              No,       The user id performing the action
      @FULLNAME:       No,       The fullname of the user
      @MACHINENAME:                  No,    The machine name where the action occurred
      @AUDITDESC:             No,       The description of the audit
      @TRANSACTION_ID:            No,       The transaction id(session id) of the action
      @SECURITY_REQUEST_TYPE:    No,       The security request type
      @SECURITY_REQUEST_RESULT:   No,       The security request result
      @SECURITY_ID:            No,       The security id of the user id(if found)
      @USER_ID:              No,       The user
      @USER_GUID:       No,       ''Y'' to cascade to child tasks; otherwise, ''N''
      @MACHINE_NAME_OR_IP:     No,       ''Y'' to cascade to child tasks; otherwise, ''N''
      @CALLING_IP:             No,       The unique identifier of the task instance to change the priority for.
      @SECURITY_GROUP:            No,       The new priority level for the task
      @SECURITY_SUBGROUP:     No,       ''Y'' to cascade to child tasks; otherwise, ''N''
      @APPLICATION_NAME:     No,       ''Y'' to cascade to child tasks; otherwise, ''N''
      @ON_BEHALF_OF_SECURITY_ID:   No,       ''Y'' to cascade to child tasks; otherwise, ''N''
      @ON_BEHALF_OF_USER_ID:     No,       ''Y'' to cascade to child tasks; otherwise, ''N''
      @ON_BEHALF_OF_SECURITY_GROUP:  No,       ''Y'' to cascade to child tasks; otherwise, ''N''
      @ON_BEHALF_OF_APPLICATION_NAME:  No,       ''Y'' to cascade to child tasks; otherwise, ''N''
      @SECURITY_DETAIL:        No,       ''Y'' to cascade to child tasks; otherwise, ''N''
Prototype:
      exec AUDITLOG.CREATE_AUDITLOG_SECURITY_ENTRY
     @AUDITAREA                     =''Login'',
     @USERID                        =''Username'',
     @FULLNAME                      =''Username'',
     @MACHINENAME                   =''MACHINENAME'',
     @AUDITDESC                     =''See detail'',
     @TRANSACTION_ID                =''02b098dc-d858-46e6-9bd9-b6ba48d769b3'',
     @SECURITY_ID                   =''6a670828-ea46-44e7-91dd-4d25595abe54'',
     @USER_ID                       =''Username'',
     @USER_GUID                     ='''',
     @MACHINE_NAME_OR_IP            =''MACHINENAME'',
     @CALLING_IP                    =''net.pipe://localhost/Services/SecurityService.svc'',
     @SECURITY_GROUP                =''LOS'',
     @SECURITY_SUBGROUP             ='''',
     @APPLICATION_NAME              =''WinUI'',
     @SECURITY_REQUEST_TYPE         =''Login'',
     @SECURITY_REQUEST_RESULT       =''Success'',
     @ON_BEHALF_OF_SECURITY_ID      ='''',
     @ON_BEHALF_OF_USER_ID          ='''',
     @ON_BEHALF_OF_SECURITY_GROUP   ='''',
     @ON_BEHALF_OF_APPLICATION_NAME  ='''',
     @SECURITY_DETAIL               ='''';
Version History
Date        Author            WI Number        Description
09/29/2014  Arch              98582            Initial Creation
08/25/2016  DBA               343115           AuditArea size discrepancy  fix
====================================================================*/
CREATE PROCEDURE [AUDITLOG].[CREATE_AUDITLOG_SECURITY_ENTRY] (
 @AUDITAREA VARCHAR(50)
 ,@USERID VARCHAR(256)
 ,@FULLNAME VARCHAR(150)
 ,@MACHINENAME VARCHAR(256)
 ,@AUDITDESC VARCHAR(250)
 ,@TRANSACTION_ID VARCHAR(36)
 ,@SECURITY_REQUEST_TYPE VARCHAR(40)
 ,@SECURITY_REQUEST_RESULT VARCHAR(40)
 ,@SECURITY_ID VARCHAR(36)
 ,@USER_ID VARCHAR(256)
 ,@USER_GUID VARCHAR(40)
 ,@MACHINE_NAME_OR_IP VARCHAR(256)
 ,@CALLING_IP VARCHAR(256)
 ,@SECURITY_GROUP VARCHAR(30)
 ,@SECURITY_SUBGROUP VARCHAR(30)
 ,@APPLICATION_NAME VARCHAR(30)
 ,@ON_BEHALF_OF_SECURITY_ID VARCHAR(36)
 ,@ON_BEHALF_OF_USER_ID VARCHAR(256)
 ,@ON_BEHALF_OF_SECURITY_GROUP VARCHAR(30)
 ,@ON_BEHALF_OF_APPLICATION_NAME VARCHAR(30)
 ,@SECURITY_DETAIL VARCHAR(max)
 )
AS
BEGIN
 SET NOCOUNT ON
 BEGIN TRANSACTION
 DECLARE @OUTPUT_TABLE TABLE (
  AUDITID BIGINT
  ,TIMESTAMP DATETIME
  )
 DECLARE @AUDITID BIGINT
  ,@TIMESTAMP DATETIME;
 INSERT INTO AUDITLOG.AUDITLOG (
  TIMESTAMP
  ,AUDITAREA
  ,USERID
  ,FULLNAME
  ,MACHINENAME
  ,AUDITDESC
  )
 OUTPUT inserted.AUDITID
  ,inserted.TIMESTAMP
 INTO @OUTPUT_TABLE
 VALUES (
  GETUTCDATE()
  ,@AUDITAREA
  ,@USERID
  ,@FULLNAME
  ,@MACHINENAME
  ,@AUDITDESC
  )
 SELECT TOP 1 @AUDITID = AUDITID
  ,@TIMESTAMP = TIMESTAMP
 FROM @OUTPUT_TABLE
 INSERT INTO AUDITLOG.AUDITLOG_SECURITY (
  AUDITID
  ,TIMESTAMP
  ,[TRANSACTION_ID]
  ,[SECURITY_REQUEST_TYPE]
  ,[SECURITY_REQUEST_RESULT]
  ,[SECURITY_ID]
  ,[USER_ID]
  ,[USER_GUID]
  ,[MACHINE_NAME_OR_IP]
  ,[CALLING_IP]
  ,[SECURITY_GROUP]
  ,[SECURITY_SUBGROUP]
  ,[APPLICATION_NAME]
  ,[ON_BEHALF_OF_SECURITY_ID]
  ,[ON_BEHALF_OF_USER_ID]
  ,[ON_BEHALF_OF_SECURITY_GROUP]
  ,[ON_BEHALF_OF_APPLICATION_NAME]
  ,[SECURITY_DETAIL]
  )
 VALUES (
  @AUDITID
  ,@TIMESTAMP
  ,@TRANSACTION_ID
  ,@SECURITY_REQUEST_TYPE
  ,@SECURITY_REQUEST_RESULT
  ,@SECURITY_ID
  ,@USER_ID
  ,@USER_GUID
  ,@MACHINE_NAME_OR_IP
  ,@CALLING_IP
  ,@SECURITY_GROUP
  ,@SECURITY_SUBGROUP
  ,@APPLICATION_NAME
  ,@ON_BEHALF_OF_SECURITY_ID
  ,@ON_BEHALF_OF_USER_ID
  ,@ON_BEHALF_OF_SECURITY_GROUP
  ,@ON_BEHALF_OF_APPLICATION_NAME
  ,@SECURITY_DETAIL
  )
 COMMIT TRANSACTION
END' 
END

SMO2018

SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[AUDITLOG].[CREATE_AUDITLOG_SECURITY_ENTRY]') AND type in (N'P', N'PC'))
BEGIN
EXEC dbo.sp_executesql @statement = N'CREATE PROCEDURE [AUDITLOG].[CREATE_AUDITLOG_SECURITY_ENTRY] AS' 
END
/*====================================================================
Object:     AUDITLOG.CREATE_AUDITLOG_SECURITY_ENTRY
Desc:       Creates an audit entry into the AUDITLOG.AUDITLOG table and the AUDITLOG.AUDITLOG_SECURITY with the supplied data.
Parameters:
Name                          Optional  Description
      @AUDITAREA:             No,       The area being audited
      @USERID:              No,       The user id performing the action
      @FULLNAME:       No,       The fullname of the user
      @MACHINENAME:                  No,    The machine name where the action occurred
      @AUDITDESC:             No,       The description of the audit
      @TRANSACTION_ID:            No,       The transaction id(session id) of the action
      @SECURITY_REQUEST_TYPE:    No,       The security request type
      @SECURITY_REQUEST_RESULT:   No,       The security request result
      @SECURITY_ID:            No,       The security id of the user id(if found)
      @USER_ID:              No,       The user
      @USER_GUID:       No,       'Y' to cascade to child tasks; otherwise, 'N'
      @MACHINE_NAME_OR_IP:     No,       'Y' to cascade to child tasks; otherwise, 'N'
      @CALLING_IP:             No,       The unique identifier of the task instance to change the priority for.
      @SECURITY_GROUP:            No,       The new priority level for the task
      @SECURITY_SUBGROUP:     No,       'Y' to cascade to child tasks; otherwise, 'N'
      @APPLICATION_NAME:     No,       'Y' to cascade to child tasks; otherwise, 'N'
      @ON_BEHALF_OF_SECURITY_ID:   No,       'Y' to cascade to child tasks; otherwise, 'N'
      @ON_BEHALF_OF_USER_ID:     No,       'Y' to cascade to child tasks; otherwise, 'N'
      @ON_BEHALF_OF_SECURITY_GROUP:  No,       'Y' to cascade to child tasks; otherwise, 'N'
      @ON_BEHALF_OF_APPLICATION_NAME:  No,       'Y' to cascade to child tasks; otherwise, 'N'
      @SECURITY_DETAIL:        No,       'Y' to cascade to child tasks; otherwise, 'N'
Prototype:
      exec AUDITLOG.CREATE_AUDITLOG_SECURITY_ENTRY
     @AUDITAREA                     ='Login',
     @USERID                        ='Username',
     @FULLNAME                      ='Username',
     @MACHINENAME                   ='MACHINENAME',
     @AUDITDESC                     ='See detail',
     @TRANSACTION_ID                ='02b098dc-d858-46e6-9bd9-b6ba48d769b3',
     @SECURITY_ID                   ='6a670828-ea46-44e7-91dd-4d25595abe54',
     @USER_ID                       ='Username',
     @USER_GUID                     ='',
     @MACHINE_NAME_OR_IP            ='MACHINENAME',
     @CALLING_IP                    ='net.pipe://localhost/Services/SecurityService.svc',
     @SECURITY_GROUP                ='LOS',
     @SECURITY_SUBGROUP             ='',
     @APPLICATION_NAME              ='WinUI',
     @SECURITY_REQUEST_TYPE         ='Login',
     @SECURITY_REQUEST_RESULT       ='Success',
     @ON_BEHALF_OF_SECURITY_ID      ='',
     @ON_BEHALF_OF_USER_ID          ='',
     @ON_BEHALF_OF_SECURITY_GROUP   ='',
     @ON_BEHALF_OF_APPLICATION_NAME  ='',
     @SECURITY_DETAIL               ='';
Version History
Date        Author            WI Number        Description
09/29/2014  Arch              98582            Initial Creation
08/25/2016  DBA               343115           AuditArea size discrepancy  fix
====================================================================*/
ALTER PROCEDURE [AUDITLOG].[CREATE_AUDITLOG_SECURITY_ENTRY] (
 @AUDITAREA VARCHAR(50)
 ,@USERID VARCHAR(256)
 ,@FULLNAME VARCHAR(150)
 ,@MACHINENAME VARCHAR(256)
 ,@AUDITDESC VARCHAR(250)
 ,@TRANSACTION_ID VARCHAR(36)
 ,@SECURITY_REQUEST_TYPE VARCHAR(40)
 ,@SECURITY_REQUEST_RESULT VARCHAR(40)
 ,@SECURITY_ID VARCHAR(36)
 ,@USER_ID VARCHAR(256)
 ,@USER_GUID VARCHAR(40)
 ,@MACHINE_NAME_OR_IP VARCHAR(256)
 ,@CALLING_IP VARCHAR(256)
 ,@SECURITY_GROUP VARCHAR(30)
 ,@SECURITY_SUBGROUP VARCHAR(30)
 ,@APPLICATION_NAME VARCHAR(30)
 ,@ON_BEHALF_OF_SECURITY_ID VARCHAR(36)
 ,@ON_BEHALF_OF_USER_ID VARCHAR(256)
 ,@ON_BEHALF_OF_SECURITY_GROUP VARCHAR(30)
 ,@ON_BEHALF_OF_APPLICATION_NAME VARCHAR(30)
 ,@SECURITY_DETAIL VARCHAR(max)
 )
AS
BEGIN
 SET NOCOUNT ON
 BEGIN TRANSACTION
 DECLARE @OUTPUT_TABLE TABLE (
  AUDITID BIGINT
  ,TIMESTAMP DATETIME
  )
 DECLARE @AUDITID BIGINT
  ,@TIMESTAMP DATETIME;
 INSERT INTO AUDITLOG.AUDITLOG (
  TIMESTAMP
  ,AUDITAREA
  ,USERID
  ,FULLNAME
  ,MACHINENAME
  ,AUDITDESC
  )
 OUTPUT inserted.AUDITID
  ,inserted.TIMESTAMP
 INTO @OUTPUT_TABLE
 VALUES (
  GETUTCDATE()
  ,@AUDITAREA
  ,@USERID
  ,@FULLNAME
  ,@MACHINENAME
  ,@AUDITDESC
  )
 SELECT TOP 1 @AUDITID = AUDITID
  ,@TIMESTAMP = TIMESTAMP
 FROM @OUTPUT_TABLE
 INSERT INTO AUDITLOG.AUDITLOG_SECURITY (
  AUDITID
  ,TIMESTAMP
  ,[TRANSACTION_ID]
  ,[SECURITY_REQUEST_TYPE]
  ,[SECURITY_REQUEST_RESULT]
  ,[SECURITY_ID]
  ,[USER_ID]
  ,[USER_GUID]
  ,[MACHINE_NAME_OR_IP]
  ,[CALLING_IP]
  ,[SECURITY_GROUP]
  ,[SECURITY_SUBGROUP]
  ,[APPLICATION_NAME]
  ,[ON_BEHALF_OF_SECURITY_ID]
  ,[ON_BEHALF_OF_USER_ID]
  ,[ON_BEHALF_OF_SECURITY_GROUP]
  ,[ON_BEHALF_OF_APPLICATION_NAME]
  ,[SECURITY_DETAIL]
  )
 VALUES (
  @AUDITID
  ,@TIMESTAMP
  ,@TRANSACTION_ID
  ,@SECURITY_REQUEST_TYPE
  ,@SECURITY_REQUEST_RESULT
  ,@SECURITY_ID
  ,@USER_ID
  ,@USER_GUID
  ,@MACHINE_NAME_OR_IP
  ,@CALLING_IP
  ,@SECURITY_GROUP
  ,@SECURITY_SUBGROUP
  ,@APPLICATION_NAME
  ,@ON_BEHALF_OF_SECURITY_ID
  ,@ON_BEHALF_OF_USER_ID
  ,@ON_BEHALF_OF_SECURITY_GROUP
  ,@ON_BEHALF_OF_APPLICATION_NAME
  ,@SECURITY_DETAIL
  )
 COMMIT TRANSACTION
END
...