为啥这个 PL/SQL 查询不使用 ODP.NET 执行
Posted
技术标签:
【中文标题】为啥这个 PL/SQL 查询不使用 ODP.NET 执行【英文标题】:Why this PL/SQL query doesn't execute using ODP.NET为什么这个 PL/SQL 查询不使用 ODP.NET 执行 【发布时间】:2014-01-21 11:55:54 【问题描述】:在我的代码中某处生成了一个查询,它将使用以下命令执行:
command.ExecuteNonQuery();
但是对于下面的查询,它会抛出这个异常:
"ORA-01036: illegal variable name/number"
奇怪的是,如果我把这个查询复制到Toad
并设置它的参数值,它执行没有任何问题。
我在command.CommandText
中设置的查询是:
declare vv2 number ;
BEGIN
:vv := '';
begin SKY.BUSINESS_OBJECT_PKG.REGISTER(B_TYPE_ID=>:B_a_TYPE_ID, B_ID=>:B_b_ID); end;
INSERT INTO GALAXY.E_CONTENTS(
CONTENT,
HASH_CODE,
FILE_NAME,
THUMBNAIL,
ID,
LOCKED_BY_ID,
TYPE_ID
)
VALUES
(
:P_c_CONTENT,
:P_d_HASH_CODE,
:P_e_FILE_NAME,
:P_f_THUMBNAIL,
:P_g_ID,
:P_h_LOCKED_BY_ID,
:P_i_TYPE_ID
);
begin SKY.BUSINESS_OBJECT_PKG.REGISTER(B_TYPE_ID=>:B_j_TYPE_ID, B_ID=>:B_k_ID); end;
INSERT INTO EVENT_MANAGEMENT.UI_EVENT(
NOTIFICATION_PORT,
WORK_ITEM,
WORK_ITEM_DESC,
BO_DESC,
BO_CHANGES_ID,
SMART_SERVICE_VALUE,
CONTEXT_ID,
CONTEXT_TYPE_ID,
DESCRIPTION,
EVENT_DATE,
CREATION_DATE,
SENDER_ID,
MACHINE,
EVENT_CATEGORY,
REFERENCE_ID,
EVENT_MODE,
HANDLED_DATE,
HISTORY,
IS_VIEWED,
IS_ACTIVE,
ID,
LOCKED_BY_ID,
TYPE_ID
)
VALUES
(
:P_l_NOTIFICATION_PORT,
:P_m_WORK_ITEM,
:P_m_WORK_ITEM_DESC,
:P_o_BO_DESC,
:P_p_BO_CHANGES_ID,
:P_q_SMART_SERVICE_VALUE,
:P_r_CONTEXT_ID,
:P_s_CONTEXT_TYPE_ID,
:P_t_DESCRIPTION,
:P_u_EVENT_DATE,
:P_v_CREATION_DATE,
:P_w_SENDER_ID,
:P_x_MACHINE,
:P_y_EVENT_CATEGORY,
:P_z_REFERENCE_ID,
:P_aa_EVENT_MODE,
:P_ab_HANDLED_DATE,
:P_ac_HISTORY,
:P_ad_IS_VIEWED,
:P_ae_IS_ACTIVE,
:P_af_ID,
:P_ag_LOCKED_BY_ID,
:P_ah_TYPE_ID
);
begin SKY.BUSINESS_OBJECT_PKG.REGISTER(B_TYPE_ID=>:B_ai_TYPE_ID, B_ID=>:B_aj_ID); end;
INSERT INTO ACCOUNTING.TRANSACTIONS(
TITLE,
LAST_CHANGE_ID,
EFFECTIVE_DATE,
CREATE_DATE,
BO_REFRENCE_ID,
CREATOR_ID,
COMPANY_ID,
VOUCHER_ID,
TRANSACTION_TYPE_VALUE,
FISCAL_YEAR_ID,
TRANSACTION_STATE_VALUE,
FYTB_ID,
REVISORY_TRANSACTION_ID,
BO_TYPE_VALUE,
TRANSACTION_NUMBER,
ID,
LOCKED_BY_ID,
TYPE_ID
)
VALUES
(
:P_ak_TITLE,
:P_al_LAST_CHANGE_ID,
:P_am_EFFECTIVE_DATE,
:P_an_CREATE_DATE,
:P_ao_BO_REFRENCE_ID,
:P_ap_CREATOR_ID,
:P_aq_COMPANY_ID,
:P_ar_VOUCHER_ID,
:P_as_TRANSACTION_TYPE_VALUE,
:P_at_FISCAL_YEAR_ID,
:P_au_TRANSACTION_STATE_VALUE,
:P_av_FYTB_ID,
:P_aw_REVISORY_TRANSACTION_ID,
:P_ax_BO_TYPE_VALUE,
:P_ay_TRANSACTION_NUMBER,
:P_az_ID,
:P_ba_LOCKED_BY_ID,
:P_bb_TYPE_ID
);
END;
仅供参考,我使用的是ODP.NET
。
为什么这样的查询会抛出这个异常?
更新 1: 在此问题之前,我曾遇到过此类问题,以下提示解决了这些问题。但在这种情况下,这些提示不起作用。
从查询中删除所有"\n"
、"\r"
、"\t"
字符。
重命名名称超过 31 个字符的所有变量。
【问题讨论】:
尝试删除 DECLARE 语句。 @BobJarvis 为什么!?此查询适用于这种结构,但插入到其他表! 【参考方案1】:可能是因为ODP.NET在某些情况下不支持'\r'字符...尝试替换
command.ExecuteNonQuery();
通过
command.CommandText = command.CommandText.Replace("\r", string.Empty);
command.ExecuteNonQuery();
【讨论】:
其实我之前测试过。但不幸的是它仍然不起作用。【参考方案2】:您应该发布其余的 .net 代码,特别是您要添加到命令中的参数。无论如何,我看到了几个潜在的问题:
一个,也许 toad 正在做一些特殊的事情,但是以下在 sql-plus 窗口中无效:
declare vv2 number ;
BEGIN
:vv := '';
end;
/
用冒号绑定变量实际上是在sql-plus“var”语句中声明的,而不是在匿名pl-sql块的declare语句中。无论如何,您似乎都没有使用该变量。仅此一项就可能是问题所在,因为它会丢弃需要绑定的参数数量。
二,这可能是典型的参数不匹配问题(再次,需要查看您的 Parameter.Add 调用)。可能是参数个数、参数类型、参数顺序等不匹配,请参考我之前的blog post。
最后,我没有尝试在一个语句中执行两个匿名块。也许一次尝试一个只是为了排除它们?我也有一个in-depth write up of calling sql-plus scripts.
【讨论】:
谢谢。我会检查你有用的建议。如果没有帮助,我会提供有关参数的更多详细信息。以上是关于为啥这个 PL/SQL 查询不使用 ODP.NET 执行的主要内容,如果未能解决你的问题,请参考以下文章
为啥我在调用 DbDataAdapter.Update 时使用 ODP.NET OracleDataAdapter 而不是使用 System.Data.OracleClient 的适配器得到 Orac
将 ODP.Net 与 NHibernate 与 .net System.decimal 一起使用