oracle data-binding oracle9i ora-01008

oracle - ORA-01008: no todas las variables están vinculadas. Ellos están atados



data-binding oracle9i (6)

Encontré cómo ejecutar la consulta sin error, pero dudo en llamarla una "solución" sin realmente entender la causa subyacente.

Esto se parece más al comienzo de mi consulta real:

-- 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 ( ...

El segundo grupo de comentarios arriba, al comienzo de la subconsulta, era el problema. Cuando se elimina, la consulta se ejecuta. Otros comentarios están bien. No se trata de una nueva línea deshonesta o faltante que hace que se comente la siguiente línea, porque la siguiente línea es un SELECCIONAR. Una selección faltante produciría un error diferente que "no todas las variables vinculadas".

Pregunté por ahí y encontré varias veces a un compañero de trabajo que se encontró con esto, comentarios que causan fallas en las consultas. ¿Alguien sabe cómo esta puede ser la causa? Entiendo que lo primero que haría un DBMS con los comentarios es ver si contienen consejos, y si no, eliminarlos durante el análisis. ¿Cómo puede un comentario ordinario que no contiene caracteres inusuales (solo letras y un punto) causar un error? Extraño.

Me encontré con un problema de Oracle para el que hasta ahora no he podido encontrar la causa. La siguiente consulta funciona en Oracle SQL developer, pero cuando se ejecuta en .NET arroja:

ORA-01008: no todas las variables vinculadas

He intentado:

  • Cambiar el tipo de datos de Oracle para lot_priority (Varchar2 o int32).
  • Cambiar el tipo de datos .NET para lot_priority (string o int).
  • Un nombre de variable de enlace se usa dos veces en la consulta. Esto no es un problema en mis otras consultas que usan la misma variable enlazada en más de una ubicación, pero solo para asegurarme de que intenté hacer de la segunda instancia su propia variable con un nombre diferente: unirlo por separado.
  • Varias formas diferentes de vincular las variables (ver código comentado, y otros).
  • Mover la llamada bindByName () alrededor.
  • Reemplazar cada variable encuadernada con un literal. He tenido dos variables separadas que causan el problema (: lot_pri y: lot_priprc). Hubo algunos cambios menores que no recuerdo entre los dos. El cambio a los literales hizo que la consulta funcionara, pero necesitan trabajar con el enlace.

Consulta y código a continuación. Los nombres de variables han sido cambiados para proteger a los inocentes:

SELECT rf.myrow floworder, rf.stage, rf.prss, rf.pin instnum, rf.prid, r_history.rt, r_history.wt FROM ( SELECT sub2.myrow, sub2.stage, sub2.prss, sub2.pin, sub2.prid FROM ( SELECT sub.myrow, sub.stage, sub.prss, sub.pin, sub.prid, MAX(sub.target_rn) OVER (ORDER BY sub.myrow) target_row ,sub.hflag FROM ( WITH floc AS ( SELECT flow.prss, flow.seq_num FROM rpf@mydblink flow WHERE flow.parent_p = :lapp AND flow.prss IN ( SELECT r_priprc.prss FROM r_priprc@mydblink r_priprc WHERE priprc = :lot_priprc ) AND rownum = 1 ) SELECT row_number() OVER (ORDER BY pp.seq_num, rpf.seq_num) myrow, rpf.stage, rpf.prss, rpf.pin, rpf.itype, hflag, CASE WHEN rpf.itype = ''SpecialValue'' THEN rpf.instruction ELSE rpf.parent_p END prid, CASE WHEN rpf.prss = floc.prss AND rpf.seq_num = floc.seq_num THEN row_number() OVER (ORDER BY pp.seq_num, rpf.seq_num) END target_rn FROM floc, rpf@mydblink rpf LEFT OUTER JOIN r_priprc@mydblink pp ON (pp.prss = rpf.prss) WHERE pp.priprc = :lot_priprc ORDER BY pp.seq_num, rpf.seq_num ) sub ) sub2 WHERE sub2.myrow >= sub2.target_row AND sub2.hflag = ''true'' ) rf LEFT OUTER JOIN r_history@mydblink r_history ON (r_history.lt = :lt AND r_history.pri = :lot_pri AND r_history.stage = rf.stage AND r_history.curp = rf.prid ) ORDER BY myrow

public void runMyQuery(string lot_priprc, string lapp, string lt, int lot_pri) { Dictionary<int, foo> bar = new Dictionary<int, foo>(); using(var con = new OracleConnection(connStr)) { con.Open(); using(var cmd = new OracleCommand(sql.rtd_get_flow_for_lot, con)) { // Query stored in sql.resx try { cmd.BindByName = true; cmd.Prepare(); cmd.Parameters.Add(new OracleParameter("lapp", OracleDbType.Varchar2)).Value = lapp; cmd.Parameters.Add(new OracleParameter("lot_priprc", OracleDbType.Varchar2)).Value = lot_priprc; cmd.Parameters.Add(new OracleParameter("lt", OracleDbType.Varchar2)).Value = lt; // Also tried OracleDbType.Varchar2 below, and tried passing lot_pri as an integer cmd.Parameters.Add(new OracleParameter("lot_pri", OracleDbType.Int32)).Value = lot_pri.ToString(); /*********** Also tried the following, more explicit code rather than the 4 lines above: ** OracleParameter param_lapp = cmd.Parameters.Add(new OracleParameter("lapp", OracleDbType.Varchar2)); OracleParameter param_priprc = cmd.Parameters.Add(new OracleParameter("lot_priprc", OracleDbType.Varchar2)); OracleParameter param_lt = cmd.Parameters.Add(new OracleParameter("lt", OracleDbType.Varchar2)); OracleParameter param_lot_pri = cmd.Parameters.Add(new OracleParameter("lot_pri", OracleDbType.Varchar2)); param_lapp.Value = lastProcedureStackProcedureId; param_priprc.Value = lotPrimaryProcedure; param_lt.Value = lotType; param_lot_pri.Value = lotPriority.ToString(); //***************************************************************/ var reader = cmd.ExecuteReader(); while(reader.Read()) { // Get values from table (Never reached) } } catch(OracleException e) { // ORA-01008: not all variables bound } } }

¿Por qué Oracle afirma que no todas las variables están vinculadas?



Sé que esta es una vieja pregunta, pero no se ha abordado correctamente, por lo que estoy respondiendo a otras personas que pueden encontrarse con este problema.

Por defecto, ODP.net de Oracle vincula variables por posición y trata cada posición como una nueva variable.

Tratar cada copia como una variable diferente y establecer su valor varias veces es una solución y una molestia, como se menciona en furman87, y podría dar lugar a errores, si está intentando reescribir la consulta y mover las cosas.

La forma correcta es establecer la propiedad BindByName de OracleCommand en verdadero de la siguiente manera:

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

También podría crear una nueva clase para encapsular OracleCommand estableciendo BindByName en verdadero en la creación de instancias, de modo que no tenga que establecer el valor cada vez. Esto se discute en this publicación


Sobre el problema de comentario de Charles: para empeorar las cosas, deja que

:p1 = ''TRIALDEV''

a través de un Parámetro de Comando, luego ejecuta

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

y al cambiar la cadena literal de === a ---

select T.table_name as NAME, COALESCE(C.comments, ''---'') as DESCRIPTION [...from...same-as-above...] ORA-01008: not all variables bound

Ambas sentencias se ejecutan correctamente en SQL Developer. El código acortado:

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

utilizando Oracle.ManagedDataAccess.dll versión 4.121.2.0 con la configuración predeterminada en VS2015 en la plataforma .Net 4.61.

Entonces, en algún lugar de la cadena de llamadas, puede haber un analizador que busque demasiado agresivamente los comentarios de una línea comenzados por: en el comandoTexto. Pero incluso si esto fuera cierto, el mensaje de error "no todas las variables vinculadas" es al menos engañoso.


Tenía un problema similar en una aplicación heredada, pero de "-" era un parámetro de cadena.

Ex.:

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

Cambiar el valor del parámetro de dirección ''-'' a ''00'' u otra cosa, funciona.


Tiene dos referencias a la variable de vinculación: lot_priprc, aunque debería exigirle que solo establezca el valor de la variable una vez y lo vincule en ambos lugares, he tenido problemas donde esto no funcionaba y tuve que tratar cada copia como una variable diferente Un dolor, pero funcionó.