2

XE2プロジェクトのリソースとして保存されている動的SQLを含む挿入トリガーがあります。また、Delphコードを実行してSQLを実行するときに置き換えられるデータベース名とテーブル名のプレースホルダーも含まれています。

元々、SqlExpressデータベースに対してDevArt SQL Serverドライバーを使用していましたが、LocalDBデータベースに対してODBCとSQLNativeClientドライバーを使用したいと考えています。

私が見つけたのは、元の作成トリガースクリプトが機能しなくなったことです。

TSQLQuery.ExecSQLを使用してSQLコマンドを実行しています。

CREATE TRIGGER [dbo].[#TableName#_INSERT_TRIGGER] ON [#DatabaseName#].[dbo].[#TableName#] FOR INSERT

を引き起こします

'[Microsoft] [SQL Server Native Client 11.0] [SQL Server]ターゲットが現在のデータベースにないため、'EvaluationCompany_COPYDB.dbo.COPY_PRODUCTS'でトリガーを作成できません。

私が使用するパーサークラスは、GOキーワードのSQLスクリプトを個別のステートメントに分割するため、createtriggerスクリプトを次のように修正しました。

USE [#DatabaseName#]
GO
CREATE TRIGGER [dbo].[#TableName#_INSERT_TRIGGER] ON [dbo].[#TableName#] FOR INSERT

これはSSMSで行うことですが、

'[Microsoft] [SQL Server Native Client 11.0] [SQLServer]オブジェクト'dbo.COPY_PRODUCTS'が存在しないか、この操作に対して無効です。

おそらく、CREATEの「現在のデータベース」は、忘れられているように見えるため、USEによって設定されたものではないためです。

SQLステートメントを1回の実行に文字列化する通常の方法を試してみました

USE [#DatabaseName#];
CREATE TRIGGER [dbo].[#TableName#_INSERT_TRIGGER] ON [dbo].[#TableName#] FOR INSERT

しかし、それは期待を投げます

'[Microsoft] [SQL Server Native Client 11.0] [SQL Server]' CREATE TRIGGER'は、クエリバッチの最初のステートメントである必要があります。

そこで、CREATE ...END全体をEXEC[#DatabaseName#]。[sys]。[sp_ExecuteSQL] N''でラップし、それを実行しようとしました。文字列変数の内容をSSMSに貼り付けると正常に実行されますが、ExecSQLに渡されると

'[Microsoft] [SQL Server Native Client 11.0] [SQLServer]プロシージャ'sp_executesql'はプロシージャオブジェクトであるため、プロシージャ'sp_executesql'の要求は失敗しました。

これは一種の無意味です。そのため、dbExpressとSQLServerネイティブクライアントを使用してテーブルにトリガーを作成する方法がわかりません。

4

1 に答える 1

1

何が問題なのか正確にはわかりませんが、次のコードを正常に実行できました。多分それはあなたに手がかりを与えるでしょう。

uses
  Data.Win.AdoDB;

procedure TForm1.Button1Click(Sender: TObject);
var
  aConnection : tAdoConnection;

  procedure InitializeAdoConnection;
  begin
    aConnection := tAdoConnection . Create ( self );

    with aConnection do
      begin
        ConnectionString :=   'Provider=MSDASQL.1;'
                            + 'Password=' + gPassword + ';'
                            + 'Persist Security Info=True;'
                            + 'User ID=' + gUserName + ';'
                            + 'Data Source=' + gOdbcAlias + ';'
                            + 'Extended Properties="DSN=' + gOdbcAlias + ';'
                            + 'UID=' + gUserName + ';'
                            + 'PWD=' + gPassword + ';'
                            + 'APP=Enterprise;'
                            + 'WSID=' + gMachineName + ';'
                            + 'DATABASE=master";'
                            + 'Initial Catalog=master';
        LoginPrompt := false;
        Connected := true;
      end;
  end;

  procedure ExecuteCommand ( const nSqlCommand : string );
  begin
    with tAdoCommand . Create ( nil ) do
      try
        Connection := aConnection;
        CommandText := nSqlCommand;
        Execute;
      finally
        Free;
      end;
  end;

  procedure QueryResults;
  begin
    with tAdoQuery . Create ( nil ) do
      try
        Connection := aConnection;
        SQL . Text := 'select * from COPY_PRODUCTS';
        Open;

        while not EOF do
          begin
            Memo1 . Lines . Add ( 'ID='
                  + inttostr ( FieldByName ( 'PRODUCT_ID' ) . AsInteger )
                  + ' Name='
                  + FieldByName ( 'PRODUCT_NAME' ) . AsString );

            Next;
          end;


      finally
        Free;
      end;
  end;

begin
  InitializeAdoConnection;

//  ExecuteCommand ( 'drop database EvaluationCompany_COPYDB' );

  ExecuteCommand ( 'create database EvaluationCompany_COPYDB' );

  ExecuteCommand ( 'use EvaluationCompany_COPYDB' );

  ExecuteCommand ( 'create table dbo.COPY_PRODUCTS '
                   + '( PRODUCT_ID int identity(1,1),'
                   + '  PRODUCT_NAME varchar(50) )' );

  ExecuteCommand ( 'create trigger dbo.COPY_PRODUCTS_INSERT_TRIGGER '
                   + 'on dbo.COPY_PRODUCTS '
                   + 'for insert '
                   + 'as '
                   + 'begin '
                   + '  update COPY_PRODUCTS '
                   + '    set PRODUCT_NAME = PRODUCT_NAME + ''!'' '
                   + '    where PRODUCT_ID in '
                   + '    ( select PRODUCT_ID from INSERTED )'
                   + 'end ' );

  ExecuteCommand ( 'insert into COPY_PRODUCTS ( product_name ) '
                   + 'values ( ''Stacky Goodness'' ) ' );

  QueryResults;
end;
于 2012-09-26T10:38:54.360 に答える