我有一个插入触发器,其中包含存储为我的XE2项目资源的动态sql。它还包含数据库名称和表名的占位符,这些占位符在Delph代码运行以执行SQL时被替换。
最初我使用的是针对SqlExpress数据库的DevArt SQL Server驱动程序,但我现在想要对LocalDB数据库使用ODBC和SQL Native Client驱动程序。
我发现我的原始创建触发器脚本不再有效。
我正在使用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脚本拆分为单独的语句,所以我修改了我的创建触发器脚本来说
USE [#DatabaseName#]
GO
CREATE TRIGGER [dbo].[#TableName#_INSERT_TRIGGER] ON [dbo].[#TableName#] FOR INSERT
这是您在SSMS中所做的,但是说
'[Microsoft] [SQL Server Native Client 11.0] [SQL Server]对象'dbo.COPY_PRODUCTS'不存在或对此操作无效。'
可能是因为CREATE的“当前数据库”不是USE设置的,因为它似乎被遗忘了。
我尝试通过执行
将sql语句串行化为单个执行的常用方法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] [SQL Server]对过程'sp_executesql'的请求失败,因为'sp_executesql'是一个过程对象。'
这是一种荒谬的。所以现在我不知道如何使用dbExpress和SQL Server本机客户端在表上创建触发器。
答案 0 :(得分: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;