ORA-01008: 모든 변수가 바인딩된 것은 아닙니다.그들은 묶여 있다.
원인을 찾을 수 없는 Oracle 문제가 발생했습니다.다음 쿼리는 Oracle SQL 개발자에서 작동하지만 에서 실행할 때는 작동합니다.투척하는 NET:
ORA-01008: 모든 변수가 바인딩된 것은 아닙니다.
시도했습니다.
- lot_priority(Varchar2 또는 int32)의 Oracle 데이터 유형 변경.
- 의 변경lot_priority의 NET 데이터 타입(string 또는 int).
- 하나의 바인드 변수 이름이 쿼리에서 두 번 사용됩니다.이것은 여러 위치에서 동일한 바인드 변수를 사용하는 다른 쿼리에서는 문제가 되지 않지만, 만약을 위해 두 번째 인스턴스를 다른 :name으로 자체 변수로 만들고 별도로 바인딩을 시도했습니다.
- 변수를 바인딩하는 몇 가지 다른 방법(댓글이 달린 코드 참조).
- bindByName() 콜 이동
- 각 바인딩 변수를 리터럴로 바꿉니다.문제의 원인에는 2개의 다른 변수(lot_pri 및 :lot_priprc)가 있습니다.둘 사이에 내가 기억할 수 없는 몇 가지 사소한 변화가 있었다.리터럴로 변경함으로써 쿼리는 정상적으로 동작하지만 바인딩으로 동작해야 합니다.
쿼리와 코드는 다음과 같습니다.변수 이름은 무고한 사람을 보호하기 위해 변경되었습니다.
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은 왜 모든 변수가 구속된 것은 아니라고 주장합니까?
오래된 질문인 것은 알지만, 제대로 대처하지 못했기 때문에, 이 문제에 부딪힐 수 있는 다른 사람들을 위해 대답합니다.
기본적으로 Oracle의 ODP.net은 위치별로 변수를 바인딩하고 각 위치를 새 변수로 취급합니다.
각 복사본을 다른 변수로 취급하여 값을 여러 번 설정하는 것은 furman87에서 설명한 바와 같이 회피책이자 번거로운 작업입니다.또한 쿼리를 다시 작성하거나 이동하려고 할 경우 버그가 발생할 수 있습니다.
올바른 방법은 다음과 같이 OracleCommand의 BindByName 속성을 true로 설정하는 것입니다.
var cmd = new OracleCommand(cmdtxt, conn);
cmd.BindByName = true;
인스턴스화 시 BindByName을 true로 설정하는 OracleCommand를 캡슐화하는 새 클래스를 만들 수도 있으므로 매번 값을 설정할 필요가 없습니다.이 투고에서는 이에 대해 설명합니다.
쿼리를 오류 없이 실행하는 방법을 찾았지만 근본 원인을 제대로 이해하지 못한 상태에서 "솔루션"이라고 부르기는 망설여집니다.
이것은 실제 질문의 시작과 매우 유사합니다.
-- 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이기 때문에 다음 행이 코멘트되는 부정한 줄이나 누락된 줄에 대한 문제가 아닙니다.선택이 누락되면 "모든 변수 바운드는 아니다"와 다른 오류가 발생합니다.
여기저기 물어보니 동료 중 한 명이 몇 번이고 이 문제에 부딪혔습니다.-댓글이 쿼리 실패를 야기하고 있습니다.이게 어떻게 원인이 되는지 아는 사람 있나요?DBMS가 코멘트에 대해 가장 먼저 실시하는 것은 코멘트에 힌트가 포함되어 있는지 확인하고, 포함되어 있지 않은 경우는 해석 중에 삭제합니다.비정상적인 문자가 없는 일반 코멘트(문자와 마침표만 포함)에서 오류가 발생할 수 있는 이유는 무엇입니까?기괴하다.
:lot_priprc binding 변수에 대한 참조가 2개 있습니다.변수 값을 한 번만 설정하고 양쪽에서 바인드하면 되는데, 이것이 동작하지 않아 각 복사본을 다른 변수로 취급해야 하는 문제가 있었습니다.고통이지만, 효과가 있었어요.
찰스의 코멘트 문제에 대해서: 설상가상으로,
: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을 사용합니다.의 VS2015 디폴트 설정으로 ManagedDataAccess.dll 버전 4.121.2.0.넷 4.61 플랫폼
따라서 콜 체인 어딘가에 commandText에서 시작하는 한 줄 코멘트를 찾는 파서가 있을 수 있습니다.그러나 이것이 사실이라고 해도 "모든 변수 바운드는 아니다"라는 오류 메시지는 적어도 오해의 소지가 있습니다.
제 상황에서의 해결책은 Charles Burns와 비슷한 답변이었습니다.문제는 SQL 코드 코멘트에 관한 것이었습니다.
Oracle 데이터 소스로 이미 기능하고 있는SSRS 보고서를 작성(또는 갱신)하고 있었습니다.리포트에 파라미터를 추가하고 Visual Studio에서 테스트했습니다.그래서 보고서 서버에 도입했습니다.보고서가 실행되면 서버에서 다음 오류 메시지가 나타납니다.
"ORA-01008: 모든 변수가 바인딩되지 않음"
서버에 설치된 TNSNames.ora 파일, 한 줄 주석 삭제, 데이터 세트 쿼리 매핑 확인 등 여러 가지 작업을 시도했습니다.결론적으로, 저는 그 후 바로 댓글 차단을 삭제해야 했습니다.WHERE keyword
에러 메세지는, 코멘트 블록을 이동한 후에 해결되었습니다.WHERE CLAUSE conditions
코드에 다른 의견도 있습니다.WHERE 키워드 뒤에 있는 것이 에러의 원인입니다.
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 。패치 23530387에서 수정된 단일 따옴표로 둘러싸인 CONST + BIND VAR IN SELECT'를 사용한 순증가 ORA-1008은 패치 24591642로 대체되었습니다.
Udemy 코스를 진행하던 중 다음 명령을 실행하다가 동일한 오류가 발생했기 때문에 도움을 요청하러 왔습니다.
INSERT INTO departments (department_id, department_name)
values( &dpet_id, '&dname');
이전에도 대체변수로 문장을 실행할 수 있었습니다.Charles Burns가 변수를 재작성할 때 서버가 임계값에 도달할 가능성에 대해 언급하자 SQL Developer를 로그아웃하고 재시작하도록 요청했습니다.다시 로그인한 후 문이 정상적으로 실행되었습니다.
내 문제처럼 제한된 범위를 가진 모험가라면 누구에게나 알려주고 싶었지
레거시 어플리케이션에서도 비슷한 문제가 발생하지만 de "--"는 문자열 파라미터입니다.
예:
새로운 Oracle Command()로서 Dim cmd사용자에게 삽입(이름, 주소, 사진) 값('User1', '--', ': photo', oracleConnection)Dim fs As IO.FileStream = 새 IO입니다.FileStream("c:\img.jpg", IO).파일 모드오픈)새로운 IO로서 DIMBr.바이너리 리더(fs)cmd.파라미터추가("새로운 Oracle Parameter("포토")), OracleDbType.Blob)) 값 = br.읽기 바이트(fs)길이)cmd.ExecuteNonQuery()는 ORA-01008을 슬로우합니다.
주소 매개 변수 값 '--'을 '00' 또는 다른 값으로 변경하면 작동합니다.
언급URL : https://stackoverflow.com/questions/7493028/ora-01008-not-all-variables-bound-they-are-bound
'programing' 카테고리의 다른 글
반응 아폴로 오류:불변 위반:컨텍스트에서 "클라이언트"를 찾을 수 없거나 옵션으로 전달되었습니다. (0) | 2023.02.13 |
---|---|
jQuery.ajax 및 FormData를 사용하여 파일을 업로드하는 방법 (0) | 2023.02.13 |
fastcgi와 fpm의 차이점은 무엇입니까? (0) | 2023.01.30 |
Java, Classpath, Classloading => 동일한 jar/프로젝트의 여러 버전 (0) | 2023.01.30 |
Array List를 셔플하는 방법 (0) | 2023.01.30 |