如何在oracle中创建更新后触发器以及如何在WPF C#应用程序中使用它
问题 我的oracle数据库中有三个表,即customer(包含客户的详细信息)、AccountDetails(包含客户帐户的详细信息)和Transaction表。现在我要做的是在oracle中创建一个触发器,它在AccountDetails(操作是取款和存款)更新后执行,当触发器执行时,它将在事务表中输入记录- T_ID非空数字(10)如何在oracle中创建更新后触发器以及如何在WPF C#应用程序中使用它,c#,.net,wpf,oracle,triggers,C#,.net,Wpf,Oracle,Triggers,问题 我的oracle数据库中有三个表,即customer(包含客户的详细信息)、AccountDetails(包含客户帐户的详细信息)和Transaction表。现在我要做的是在oracle中创建一个触发器,它在AccountDetails(操作是取款和存款)更新后执行,当触发器执行时,它将在事务表中输入记录- T_ID非空数字(10) 客户ID非空编号(10) ACC_NO NOT NULL NUMBER(10) T_型VARCHAR2(20) T_金额编号(20,2) 日期时间日期 现在我
客户ID非空编号(10)
ACC_NO NOT NULL NUMBER(10)
T_型VARCHAR2(20) T_金额编号(20,2) 日期时间日期 现在我不知道如何在事务表中创建触发器和插入值。 T_type列中的值应该是基于交易的贷方或借方,并且只有在我从这些函数中发送要插入的值时才能发送。但是如何发送呢 ViewModelCode
private void Transactions(object obj)
{
Transactions tr = new Transactions();
TransactionsViewModel trvm = new TransactionsViewModel(Id);
tr.DataContext = trvm;
tr.Show();
}
private void Withdraw(object obj)
{
try
{
con = new OracleConnection(connectionString);
con.Open();
OracleDataReader reader;
cmd = new OracleCommand($"Select Acc_No,Balance from Account_Details where PIN='{Convert.ToInt32(Pin)}'", con);
reader = cmd.ExecuteReader();
if (reader.Read())
{
if((Amount>0) && (Convert.ToInt32(reader.GetValue(1))>Amount))
{
cmd = new OracleCommand($"Update Account_Details SET Balance=Balance -'{Amount}' where Customer_ID='{Id}' and PIN='{Pin}'", con);
int n=cmd.ExecuteNonQuery();
if (n > 0)
{
cmd = new OracleCommand($"Select Balance from Account_Details where PIN='{Convert.ToInt32(Pin)}'", con);
reader = cmd.ExecuteReader();
MessageBox.Show("Remaining Balance:" + reader.GetValue(0));
}
}
else
{
MessageBox.Show("Insufficient balance");
}
}
else
{
MessageBox.Show("Incorrect PIN");
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString());
}
finally
{
con.Close();
con.Dispose();
}
}
private void Deposit(object obj)
{
try
{
con = new OracleConnection(connectionString);
con.Open();
OracleDataReader reader;
if (Amount > 0 && Pin!=null)
{
cmd = new OracleCommand($"Update Account_Details SET Balance=Balance +'{Amount}' where Customer_ID='{Id}' and PIN='{Pin}'", con);
int n=cmd.ExecuteNonQuery();
if(n>0)
{
cmd = new OracleCommand($"Select Balance from Account_Details where PIN='{Convert.ToInt32(Pin)}'", con);
reader = cmd.ExecuteReader();
MessageBox.Show("Current Balance:" +reader.GetValue(0));
}
else
{
MessageBox.Show("Incorrect PIN");
}
}
else
{
MessageBox.Show("Enter a valid amount");
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString());
}
finally
{
con.Close();
con.Dispose();
}
}
使用触发器中的:NEW和:OLD值来确定余额是增加了还是减少了,并动态分配T_类型
CREATE OR REPLACE TRIGGER transaction_trg
AFTER UPDATE ON account_details
FOR EACH ROW
DECLARE
v_t_type varchar2(20);
BEGIN
CASE
WHEN :old.balance > :new.balance THEN v_t_type := 'withdraw'
WHEN :old.balance < :new.balance THEN v_t_type := 'deposit'
ELSE v_t_type := 'none'
END CASE;
-- assuming that customer_id and acc_no are fields in the account_details
-- table (and are thus part of the transaction that fired the trigger)
-- and that t_id is a number provided by a database sequence...
IF v_t_type IN ('withdraw','deposit') THEN
INSERT INTO TRANSACTION (T_ID, CUSTOMER_ID, ACC_NO, T_TYPE)
VALUES (t_id_seq.nextval, :new.customer_id, :new.acc_no, v_t_type);
END IF;
END transaction_trg;
/
创建或替换触发器事务\u trg
更新帐户详细信息后
每行
声明
v_t_型varchar2(20);
开始
案例
当:old.balance>:new.balance然后v_t_类型:='draw'
当:old.balance<:new.balance然后v_t_类型:=“存款”
其他v_t_类型:='无'
终例;
--假设客户id和帐户编号是帐户详细信息中的字段
--表(因此是触发触发器的事务的一部分)
--这个t_id是一个由数据库序列提供的数字。。。
如果v_t_输入('draw','deposit'),那么
插入交易(T\U ID、客户ID、账号、T\U类型)
值(t_id_seq.nextval、:new.customer_id、:new.acc_no、v_t_type);
如果结束;
结束交易;
/
我得到了我问题的答案:
create or replace trigger Transaction_trg
after update on Account_details
for each row
declare
pragma autonomous_transaction;
begin
if(:New.Balance <> :Old.Balance) then
if(:New.Balance < :old.Balance) then
insert into transactions(T_ID,Customer_ID,Acc_No,T_Type,T_Amount,T_DateTime) values(TransactionId.nextval,:old.Customer_Id,:Old.Acc_No,'Debit',(:old.Balance-:New.Balance),sysdate);
commit ;
end if;
if(:New.Balance > :old.Balance) then
insert into transactions(T_ID,Customer_ID,Acc_No,T_Type,T_Amount,T_DateTime) values(TransactionId.nextval,:old.Customer_Id,:Old.Acc_No,'Credit',(:New.Balance-:OLd.Balance),sysdate);
commit;
end if;
end if;
end;
创建或替换触发器事务\u trg
更新帐户详细信息后
每行
声明
布拉格自治交易;
开始
如果(:New.Balance:Old.Balance)那么
如果(:New.Balance<:old.Balance),则
将值(TransactionId.nextval、:old.Customer\u ID、:old.Acc\u No、'Debit'、(:old.Balance-:New.Balance)、sysdate)插入交易(T\u ID、客户ID、账户编号、T\u类型、T\u金额、T\u日期时间)中;
犯罪
如果结束;
如果(:New.Balance>:old.Balance),则
将值(TransactionId.nextval、:old.Customer\u ID、:old.Acc\u No、'Credit'、(:New.Balance-:old.Balance)、sysdate)插入交易(T\u ID、客户ID、账户编号、T\u类型、T\u金额、T\u日期时间)中;
犯罪
如果结束;
如果结束;
结束;
我可以提出一些改进代码的建议吗?:使您的条件更像是保护声明:检查“不好”条件,如果满足条件,则尽早退出该方法。这将使您的代码更易于阅读。您还应该使用using
语句,并为连接对象设置一个局部变量。我还建议使用参数化SQL查询,并使用两个单独的OracleCommand变量。这些建议与您的问题无关,我只是想帮助您改进现有代码。谢谢您的建议。我将尝试改进我的代码。然后v_t_类型:='Debit'amount=:old.balance-:new.balance然后v_t_类型:='Credit'amount=:new.balance-:old.balance我为上述金额添加了一些代码,但仍然显示错误-无效的sql语句。请帮助@pmdbaamount:=:old.balance-:new.balance这是添加的行。它仍然显示编译错误的成功,不要在触发器中放入提交或自治_事务。提交必须来自父事务,否则如果触发事务或您的自治事务因任何原因回滚,您将导致数据损坏。触发的插入应始终是与插入帐户详细信息相同的交易的一部分。