私はこれまでのところ原因を見つけることができなかったOracleの問題に遭遇しました。以下のクエリはOracle SQL Developerで機能しますが、.NETで実行するとスローされます。
ORA-01008:すべての変数がバインドされていません
私はもう試した:
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
}
}
}
すべての変数がバインドされているわけではないとOracleが主張しているのはなぜですか?
エラーなしでクエリを実行する方法を見つけましたが、根本的な原因を本当に理解せずに「ソリューション」と呼ぶのをためらいます。
これは、実際のクエリの始まりにより似ています。
-- 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 ( ...
サブクエリの先頭にある上記のコメントの2番目のセットが問題でした。削除すると、クエリが実行されます。他のコメントは結構です。これは、次の行がSELECTであるため、次の行がコメントされる原因となる、不正または改行の問題ではありません。欠落している選択は、「すべての変数がバインドされていない」とは異なるエラーを生成します。
私は周りに尋ねて、これに遭遇した同僚を見つけました-クエリの失敗を引き起こすコメント-数回。誰がこれが原因になるのか知っていますか? DBMSがコメントで最初に行うことは、ヒントにヒントが含まれているかどうかを確認し、含まれていない場合は解析中にそれらを削除することです。異常な文字(文字とピリオドのみ)を含まない通常のコメントでエラーが発生する可能性はありますか?奇妙な。
これは古い質問ですが、正しく対処されていないため、この問題に遭遇する可能性のある他の人に答えています。
デフォルトでは、OracleのODP.netは変数を位置でバインドし、各位置を新しい変数として扱います。
Furman87が述べたように、各コピーを異なる変数として扱い、その値を複数回設定するのは回避策であり、苦痛であり、クエリを書き直して物事を移動しようとすると、バグにつながる可能性があります。
正しい方法は、次のようにOracleCommandのBindByNameプロパティをtrueに設定することです。
var cmd = new OracleCommand(cmdtxt, conn);
cmd.BindByName = true;
インスタンス化時にBindByNameをtrueに設定するOracleCommandをカプセル化する新しいクラスを作成することもできるため、毎回値を設定する必要はありません。これは this postで説明されています
:lot_priprcバインディング変数への2つの参照がありますが、should変数の値を一度設定して両方の場所でバインドする必要がありますが、これが機能しない問題があり、各コピーを異なる変数として扱う必要がありました。痛みが、それは働いた。
Udemyコースを受講中に以下のステートメントを実行する際に同じエラーが発生したため、ヘルプを探しに来ました。
INSERT INTO departments (department_id, department_name)
values( &dpet_id, '&dname');
以前は、置換変数を使用してステートメントを実行できました。変数を再作成している間にサーバーが何らかのしきい値に達する可能性についてCharles Burnsがコメントしたため、ログアウトしてSQL Developerを再起動するよう促されました。再度ログインした後、ステートメントは正常に実行されました。
私のスコープスコープが限られているため、ここで冒険している他の人と共有したいと思います。
私の状況での解決策は、チャールズバーンズと同様の答えでした。問題はSQLコードのコメントに関連していました。
Oracleデータソースを使用して既に機能しているSSRSレポートを作成(または更新)していました。レポートにパラメーターを追加し、Visual Studioでテストし、正常に機能するため、レポートサーバーに展開し、レポートをサーバーで実行すると、エラーメッセージが表示されました。
「ORA-01008:すべての変数がバインドされているわけではありません」
さまざまなことを試しました(サーバーにインストールされたTNSNames.oraファイル、単一行のコメントの削除、データセットクエリマッピングの検証)。結局のところ、_WHERE keyword
_の直後にコメントブロックを削除する必要がありました。エラーメッセージは、_WHERE CLAUSE conditions
_の後にコメントブロックを移動した後に解決されました。コードには他にもコメントがあります。エラーの原因となったWHEREキーワードの後の1つだけでした。
SQLエラー:「ORA-01008:すべての変数がバインドされていません」...
_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)
_
SQLはレポートサーバーで正常に実行されます...
_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
*/
_
データセットパラメータマッピング画面は次のようになります。
Managed ODP.netのバグ- 'Bug 21113901:MANAGED ODP.NET RAISE ORA-1008 Using USING QUOTED CONST + BIND VAR IN SELECT' 修正済みパッチ23530387でパッチ24591642に置き換えられました
チャールズのコメント問題について:事態を悪化させるために、
: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
リテラル文字列を===から---に変更するとき
select T.table_name as NAME, COALESCE(C.comments, '---') as DESCRIPTION
[...from...same-as-above...]
ORA-01008: not all variables bound
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
oracle.ManagedDataAccess.dllバージョン4.121.2.0を.Net 4.61プラットフォーム上のVS2015のデフォルト設定で使用します。
そのため、コールチェーンのどこかに、commandTextで-によって開始される1行コメントを探しているパーサーが少し強すぎるかもしれません。しかし、これが真実であっても、「すべての変数がバインドされていない」というエラーメッセージは、少なくとも誤解を招くものです。
従来のアプリケーションでも同様の問題がありましたが、de "-"は文字列パラメーターでした。
例:
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
アドレスパラメータ値「-」を「00」またはその他のものに変更すると、機能します。