Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/262.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ORA-01008:并非所有变量都已绑定。他们受到约束_C#_Oracle_Data Binding_Oracle9i_Ora 01008 - Fatal编程技术网

C# ORA-01008:并非所有变量都已绑定。他们受到约束

C# ORA-01008:并非所有变量都已绑定。他们受到约束,c#,oracle,data-binding,oracle9i,ora-01008,C#,Oracle,Data Binding,Oracle9i,Ora 01008,我遇到了一个甲骨文问题,到目前为止我还无法找到原因。 以下查询在Oracle SQL developer中工作,但在.NET中运行时会抛出: ORA-01008:并非所有变量都已绑定 我试过: 更改lot_优先级(Varchar2或int32)的Oracle数据类型 更改lot_优先级(字符串或int)的.NET数据类型 一个绑定变量名在查询中使用了两次。这在我看来不是问题 在多个查询中使用同一绑定变量的其他查询 位置,但只是为了确保我试着让第二个实例 使用不同的名称拥有变量,并单独绑定它 绑

我遇到了一个甲骨文问题,到目前为止我还无法找到原因。 以下查询在Oracle SQL developer中工作,但在.NET中运行时会抛出:

ORA-01008:并非所有变量都已绑定

我试过:

  • 更改lot_优先级(Varchar2或int32)的Oracle数据类型
  • 更改lot_优先级(字符串或int)的.NET数据类型
  • 一个绑定变量名在查询中使用了两次。这在我看来不是问题 在多个查询中使用同一绑定变量的其他查询 位置,但只是为了确保我试着让第二个实例 使用不同的名称拥有变量,并单独绑定它
  • 绑定变量的几种不同方式(参见注释代码; 还有其他人)
  • 移动bindByName()调用
  • 用文本替换每个绑定变量。我有两个独立的变量导致了这个问题(:lot\u pri和:lot\u priprc)。两人之间有一些细微的变化我记不得了。更改为文本使查询工作,但它们确实需要使用绑定
查询和代码跟踪。变量名已更改,以保护用户:
public void runMyQuery(字符串lot\u priprc、字符串lapp、字符串lt、int lot\u pri){
字典栏=新字典();
使用(var con=neworacleconnection(connStr)){
con.Open();
使用(var cmd=newOracleCommand(sql.rtd\u get\u flow\u for\u lot,con)){//sql.resx中存储的查询
试一试{
cmd.BindByName=true;
cmd.Prepare();
cmd.Parameters.Add(新的OracleParameter(“lapp”,OracleDbType.Varchar2)).Value=lapp;
cmd.Parameters.Add(新的OracleParameter(“lot\u priprc”,OracleDbType.Varchar2)).Value=lot\u priprc;
cmd.Parameters.Add(新的OracleParameter(“lt”,OracleDbType.Varchar2)).Value=lt;
//还尝试了下面的OracleDbType.Varchar2,并尝试将lot_pri作为整数传递
cmd.Parameters.Add(新的OracleParameter(“lot_pri”,OracleDbType.Int32)).Value=lot_pri.ToString();
/***********还尝试了以下更明确的代码,而不是上面的4行:**
OracleParameter参数
=cmd.Parameters.Add(新的OracleParameter(“lapp”,OracleDbType.Varchar2));
OracleParameter参数priprc
=cmd.Parameters.Add(新的OracleParameter(“lot_priprc”,OracleDbType.Varchar2));
OracleParameter参数
=cmd.Parameters.Add(新的OracleParameter(“lt”,OracleDbType.Varchar2));
OracleParameter param_lot_pri
=cmd.Parameters.Add(新的OracleParameter(“lot_pri”,OracleDbType.Varchar2));
param_lapp.Value=lastProcedureStackProcedureId;
param_priprc.Value=lotPrimaryProcedure;
参数值=乐透类型;
param_lot_pri.Value=lotPriority.ToString();
//***************************************************************/
var reader=cmd.ExecuteReader();
while(reader.Read()){
//从表中获取值(从未达到)
}
}
catch(oraclee异常){
//ORA-01008:并非所有变量都已绑定
}
}
}


为什么Oracle声称并非所有变量都是绑定的?

您有两个对:lot\u priprc绑定变量的引用——虽然它应该只要求您设置变量的值一次并在两个位置绑定它,但我遇到了一些问题,这不起作用,必须将每个副本视为不同的变量。这很痛苦,但它起了作用。

I f我想知道如何运行查询而不出错,但在没有真正理解根本原因的情况下,我不敢称之为“解决方案”

这与我实际查询的开始更为相似:

-- Comment
-- More comment
SELECT rf.flowrow, rf.stage, rf.process,
rf.instr instnum, rf.procedure_id, rtd_history.runtime, rtd_history.waittime
FROM
(
    -- Comment at beginning of subquery
    -- These two comment lines are the problem
    SELECT sub2.flowrow, sub2.stage, sub2.process, sub2.instr, sub2.pid
    FROM ( ...
上面第二组注释位于子查询的开头,是问题所在。删除后,查询将执行。其他注释也可以。 这不是由于某些错误或缺少换行符而导致对下一行进行注释的问题,因为下一行是SELECT。缺少SELECT将产生与“并非所有变量都绑定”不同的错误

我四处打听,发现一位同事多次遇到这种情况——注释导致查询失败。
有人知道这是怎么回事吗?据我所知,DBMS处理注释的第一件事就是查看它们是否包含提示,如果不包含,则在解析过程中删除它们。一条普通的注释怎么可能不包含异常字符(只有字母和句点)导致错误?奇怪。

我知道这是一个老问题,但没有正确解决,所以我为可能遇到此问题的其他人回答这个问题

默认情况下,Oracle的ODP.net按位置绑定变量,并将每个位置视为一个新变量

如furman87所述,将每个副本视为不同的变量并多次设置其值是一种变通方法,也是一种痛苦,如果您试图重写查询并四处移动,可能会导致错误

正确的方法是将OracleCommand的BindByName属性设置为true,如下所示:

var cmd = new OracleCommand(cmdtxt, conn);
cmd.BindByName = true;

您还可以创建一个新类来封装OracleCommand,在实例化时将BindByName设置为true,这样您就不必每次都设置该值。这将在有关Charles注释问题的post

中讨论:为了让事情变得更糟,让

:p1 = 'TRIALDEV'
通过命令参数,然后执行

select T.table_name as NAME, COALESCE(C.comments, '===') as DESCRIPTION
from all_all_tables T
Inner Join all_tab_comments C on T.owner = C.owner and T.table_name = C.table_name
where Upper(T.owner)=:p1
order by T.table_name

558 line(s) affected. Processing time: 00:00:00.6535711
将文本字符串从===更改为---

这两条语句在SQL Developer中都可以正常执行。缩短的代码:

            Using con = New OracleConnection(cs)
                con.Open()
                Using cmd = con.CreateCommand()
                    cmd.CommandText = cmdText
                    cmd.Parameters.Add(pn, OracleDbType.NVarchar2, 250).Value = p
                    Dim tbl = New DataTable
                    Dim da = New OracleDataAdapter(cmd)
                    da.Fill(tbl)
                    Return tbl
                End Using
            End Using
在.Net 4.61平台上,使用VS2015中具有默认设置的Oracle.ManagedDataAccess.dll版本4.121.2.0

因此,在调用链中的某个地方,可能有一个解析器过于积极地在commandText中查找以--开头的单行注释
select T.table_name as NAME, COALESCE(C.comments, '===') as DESCRIPTION
from all_all_tables T
Inner Join all_tab_comments C on T.owner = C.owner and T.table_name = C.table_name
where Upper(T.owner)=:p1
order by T.table_name

558 line(s) affected. Processing time: 00:00:00.6535711
select T.table_name as NAME, COALESCE(C.comments, '---') as DESCRIPTION
[...from...same-as-above...]

ORA-01008: not all variables bound
            Using con = New OracleConnection(cs)
                con.Open()
                Using cmd = con.CreateCommand()
                    cmd.CommandText = cmdText
                    cmd.Parameters.Add(pn, OracleDbType.NVarchar2, 250).Value = p
                    Dim tbl = New DataTable
                    Dim da = New OracleDataAdapter(cmd)
                    da.Fill(tbl)
                    Return tbl
                End Using
            End Using
Dim cmd As New OracleCommand("INSERT INTO USER (name, address, photo) VALUES ('User1', '--', :photo)", oracleConnection) Dim fs As IO.FileStream = New IO.FileStream("c:\img.jpg", IO.FileMode.Open) Dim br As New IO.BinaryReader(fs) cmd.Parameters.Add(New OracleParameter("photo", OracleDbType.Blob)).Value = br.ReadBytes(fs.Length) cmd.ExecuteNonQuery() 'here throws ORA-01008
INSERT INTO departments (department_id, department_name)
                  values( &dpet_id, '&dname');  
WHERE
/*
    OHH.SHIP_DATE BETWEEN TO_DATE('10/1/2018', 'MM/DD/YYYY') AND TO_DATE('10/31/2018', 'MM/DD/YYYY')
    AND OHH.STATUS_CODE<>'DL'
    AND OHH.BILL_COMP_CODE=100
    AND OHH.MASTER_ORDER_NBR IS NULL
*/

    OHH.SHIP_DATE BETWEEN :paramStartDate AND :paramEndDate
    AND OHH.STATUS_CODE<>'DL'
    AND OHH.BILL_COMP_CODE IN (:paramCompany)
    AND LOAD.DEPART_FROM_WHSE_CODE IN (:paramWarehouse) 
    AND OHH.MASTER_ORDER_NBR IS NULL
    AND LOAD.CLASS_CODE IN (:paramClassCode) 
    AND CUST.CUST_CODE || '-' || CUST.CUST_SHIPTO_CODE IN (:paramShipto) 
WHERE
    OHH.SHIP_DATE BETWEEN :paramStartDate AND :paramEndDate
    AND OHH.STATUS_CODE<>'DL'
    AND OHH.BILL_COMP_CODE IN (:paramCompany)
    AND LOAD.DEPART_FROM_WHSE_CODE IN (:paramWarehouse) 
    AND OHH.MASTER_ORDER_NBR IS NULL
    AND LOAD.CLASS_CODE IN (:paramClassCode) 
    AND CUST.CUST_CODE || '-' || CUST.CUST_SHIPTO_CODE IN (:paramShipto)   
/*
    OHH.SHIP_DATE BETWEEN TO_DATE('10/1/2018', 'MM/DD/YYYY') AND TO_DATE('10/31/2018', 'MM/DD/YYYY')
    AND OHH.STATUS_CODE<>'DL'
    AND OHH.BILL_COMP_CODE=100
    AND OHH.MASTER_ORDER_NBR IS NULL
*/