使用 C# 中的存储过程更新 Oracle 表 Odd bug
Posted
技术标签:
【中文标题】使用 C# 中的存储过程更新 Oracle 表 Odd bug【英文标题】:Updating Oracle Table using Stored Procedure from C# Odd bug 【发布时间】:2011-10-01 21:05:11 【问题描述】:如果用户已存在于数据库中,我正在使用存储过程插入新用户或更新其现有信息。
我正在从 Active Directory 中获取 3 个参数(用户名、名字和姓氏),并使用 4 个文本框来获取其余参数(PI 代码、电话、电子邮件、地址)。
<asp:TextBox ID="TXT_PI_CODE" runat="server" style="position: absolute; left:120px; top:100px;"></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator_PI_CODE" runat="server" ErrorMessage="" ControlToValidate="TXT_PI_CODE"></asp:RequiredFieldValidator>
<br />
<asp:TextBox ID="TXT_EMAIL" runat="server" style="position: absolute; left:120px; top:140px;"></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator_EMAIL" runat="server" ErrorMessage="" ControlToValidate="TXT_EMAIL"></asp:RequiredFieldValidator>
<asp:RegularExpressionValidator ID="RegularExpressionValidator_EMAIL" runat="server" ErrorMessage="Invalid Email Format." ControlToValidate="TXT_EMAIL" style="position: absolute; top:140px; left:300px;" ValidationExpression="[a-z0-9!#$%&'*+/=?^_`|~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`|~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?"></asp:RegularExpressionValidator>
<br />
<asp:TextBox ID="TXT_PHONE" runat="server" style="position: absolute; left:120px; top:180px;"></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator_PHONE" runat="server" ErrorMessage="" ControlToValidate="TXT_PHONE"></asp:RequiredFieldValidator>
<br />
<asp:TextBox ID="TXT_ADDRESS" runat="server" style="position: absolute; left:120px; top:220px;" Width="200"></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator_ADDRESS" runat="server" ErrorMessage="" ControlToValidate="TXT_ADDRESS"></asp:RequiredFieldValidator>
<br />
<asp:Label ID="LBL_REQUIRED" runat="server" Text="*Required Fields" CssClass="labels" style="position: absolute; top:260px;" ForeColor="#FF9900"></asp:Label>
<asp:Button ID="BTN_SUBMIT" runat="server" Text="Submit"
style="position: absolute; top:300px; left:120px;" Width="100" Height="40"
OnClick="BTN_SUBMIT_Click"/>
我的存储过程如下:
create or replace
PROCEDURE SP_ADD_USER
(
p_USER_NAME IN T_USER.USER_NAME%TYPE,
p_FIRST_NAME IN T_USER.FIRST_NAME%TYPE,
p_LAST_NAME IN T_USER.LAST_NAME%TYPE,
p_PI_CODE IN T_USER.PI_CODE%TYPE,
p_EMAIL IN T_USER.EMAIL%TYPE,
p_PHONE IN T_USER.PHONE%TYPE,
p_ADDRESS IN T_USER.ADDRESS%TYPE
)
AS
BEGIN
INSERT INTO T_USER (USER_ID, USER_NAME, FIRST_NAME, LAST_NAME, PI_CODE, EMAIL, PHONE, ADDRESS)
VALUES (S_USER.NEXTVAL, p_USER_NAME, p_FIRST_NAME, p_LAST_NAME, p_PI_CODE, p_EMAIL, p_PHONE, p_ADDRESS);
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
UPDATE T_USER
SET
PI_CODE = p_PI_CODE,
EMAIL = p_EMAIL,
PHONE = p_PHONE,
ADDRESS = p_ADDRESS
WHERE LOWER(USER_NAME) = p_USER_NAME;
COMMIT;
END;
最后我的 C# 看起来像这样:
protected void BTN_SUBMIT_Click(object sender, EventArgs e)
//Retrieve Username, firstname, and last name from AD.
string STR_USER_ID = ADQuery.ExtractUserName(User.Identity.Name.ToString());
string STR_FIRST_NAME = ADQuery.GetADValue(STR_USER_ID, "givenName");
string STR_LAST_NAME = ADQuery.GetADValue(STR_USER_ID, "SN");
string connectionString = WebConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
using(OracleConnection connection = new OracleConnection(connectionString))
connection.Open();
OracleCommand ora_cmd = new OracleCommand("SP_ADD_USER", connection);
ora_cmd.BindByName = true;
ora_cmd.CommandType = CommandType.StoredProcedure;
ora_cmd.Parameters.Add("p_USER_NAME", OracleDbType.Varchar2, STR_USER_ID.ToLower(), ParameterDirection.Input);
ora_cmd.Parameters.Add("p_FIRST_NAME", OracleDbType.Varchar2, STR_FIRST_NAME, ParameterDirection.Input);
ora_cmd.Parameters.Add("p_LAST_NAME", OracleDbType.Varchar2, STR_LAST_NAME, ParameterDirection.Input);
ora_cmd.Parameters.Add("p_PI_CODE", OracleDbType.Varchar2, TXT_PI_CODE.Text, ParameterDirection.Input);
ora_cmd.Parameters.Add("p_EMAIL", OracleDbType.Varchar2, TXT_EMAIL.Text, ParameterDirection.Input);
ora_cmd.Parameters.Add("p_PHONE", OracleDbType.Varchar2, TXT_PHONE.Text, ParameterDirection.Input);
ora_cmd.Parameters.Add("p_ADDRESS", OracleDbType.Varchar2, TXT_ADDRESS.Text, ParameterDirection.Input);
ora_cmd.ExecuteNonQuery();
Response.Redirect("Default.aspx");
插入部分作为新用户可以正常工作,但是当尝试更新相同文本框中的信息时,回发后数据库上没有任何更新。然而奇怪的是,如果我将 C# 更改为
ora_cmd.Parameters.Add("p_PI_CODE", OracleDbType.Varchar2, TXT_EMAIL.Text, ParameterDirection.Input);
ora_cmd.Parameters.Add("p_EMAIL", OracleDbType.Varchar2, TXT_EMAIL.Text, ParameterDirection.Input);
如果这两个参数都是从同一个文本框中填充的,它将使用电子邮件地址文本框中最初的内容更新数据库中的PI_CODE
字段,但数据库中的电子邮件地址将保持不变。
我不知道是否有一些我遗漏的错误或我的语法关闭?我已经确定我的参数顺序是正确的,或者我认为是正确的。有人见过这个吗?
【问题讨论】:
所以我弄清楚了发生的事情背后的逻辑。在我的 Page_Load 中,如果用户已经存在,我会从数据库中自动填充文本框。所以更新工作正常,应用程序只是使用文本框中的预加载值来更新并忽略所做的任何更改。这是视图状态问题吗? 想出了如何修复忽略更改的文本框。将文本框填充代码放在 if(!IsPostback) 中允许程序使用文本框中新更新的值而不是旧值。希望这对某人有所帮助。 【参考方案1】:想出了如何修复忽略更改的文本框。将文本框填充代码放在 if(!IsPostback) 中允许程序使用文本框中新更新的值而不是旧值。希望这对某人有所帮助。
【讨论】:
以上是关于使用 C# 中的存储过程更新 Oracle 表 Odd bug的主要内容,如果未能解决你的问题,请参考以下文章
SqlServer创建表,可能用到存储过程,大牛露个面,进来赐教啦!O(∩_∩)O哈哈~