source

ORA-01036: C#을 통해 쿼리를 실행할 때 잘못된 변수 이름/번호

ittop 2023. 7. 1. 09:59
반응형

ORA-01036: C#을 통해 쿼리를 실행할 때 잘못된 변수 이름/번호

는 사하려합니다고를 하려고 합니다.ALTER USER다음 코드의 C#에 있는 Oracle Command를 사용하여 Oracle 데이터베이스를 쿼리합니다.Username(사용자 이름) 및 password(암호) 값이 빈 문자열이 아닌 경우 쿼리를 만듭니다.하지만 오류가 발생합니다."ORA-01036: illegal variable name/number" 때에ExecuteNonQuery()실행됩니다.

  string updateQuery = "ALTER USER :user IDENTIFIED BY :password";
  connection = new OracleConnection(LoginPage.connectionString);
  connection.Open();                
  OracleCommand cmd = new OracleCommand(updateQuery, connection);
  cmd.Connection = connection;  
  for(int i=0;i<usersList.Count;i++)
        {
            if (!(selectedUsersArray[i].Equals("")) && !passwordArray[i].Equals(""))
            {
                OracleParameter userName = new OracleParameter();
                userName.ParameterName = "user";
                userName.Value = selectedUsersArray[i];

                OracleParameter passwd = new OracleParameter();
                passwd.ParameterName = "password";
                passwd.Value = passwordArray[i];

                cmd.Parameters.Add(userName);
                cmd.Parameters.Add(passwd);

                cmd.Prepare();
                cmd.ExecuteNonQuery();                   


            }
        }

제가 시행하는 것에 어떤 문제가 있는지 제안해 주시겠습니까?

근본 원인

Oracle에는 세 가지 유형의 SQL 문이 있습니다(또한 PL/SQL 블록도 있습니다).

  • DDL(데이터 정의 언어)의 문입니다.이러한 문은 데이터베이스의 구조를 수정합니다.그들은 보통 "ALTER" 또는 "CREATE"라는 동사로 시작합니다.
  • 데이터 수정 언어(DML)의 문입니다.재설정 문은 테이블 내부의 내용을 수정하여 각 테이블의 구조를 수정하지 않습니다.이러한 문은 일반적으로 "INSERT", "MERGE" 또는 "DELETE"로 시작합니다.
  • 제가 "쿼리 언어"라고 부르는 문장(이것들에 대한 표준 이름은 없는 것 같습니다).이 문은 동사 "SELECT"로 시작합니다.

Oracle의 바인딩 변수는 DML 및 쿼리 문의 일부 특수 위치에서만 허용됩니다.바인딩 변수가 허용되지 않는 위치에서 사용하려고 합니다.따라서 오류가 발생합니다.

해결책

바인딩 변수 없이 문을 작성합니다.문자열 연결을 사용하는 대신 전체 쿼리 문자열을 작성합니다.

문자열을 연결하기 전에 입력을 검사하려면 DBMS_ASSERT 패키지를 사용합니다.

배경

바인딩 변수는 Oracle이 변수의 값을 몰라도 쿼리 계획을 작성할 수 있는 경우에만 사용할 수 있습니다.DDL 문에는 쿼리 계획이 없습니다.따라서 바인딩 변수는 허용되지 않습니다.

DML 및 쿼리 문에서 바인딩 변수는 튜플 내에서 사용될 때(기본 집합 이론과 관련하여), 즉 값을 테이블의 값과 비교할 때 또는 테이블에 값이 삽입될 때만 허용됩니다.이들은 실행 계획의 구조를 변경할 수 없습니다(예: 대상 테이블을 변경하거나 비교 횟수를 변경할 수 없습니다.

다른 사용자가 이 오류를 확인하고 이 오류에 대한 정보를 찾는 경우 바인딩 매개 변수를 전달했지만 사용하지 않는 경우에도 마찬가지입니다.저는 그것이 어디에서도 명확하게 명시된 것을 찾을 수 없었지만 시행착오를 통해 그것을 증명해야 했습니다.

저장 프로시저에 60을 넘겨야 하기 때문에 파라미터를 확인하는 데 며칠을 보냈습니다.변수 이름 중 하나(목록에 로드하여 내가 만든 Oracle Write 메서드로 전달)의 끝에 공백이 있는 것으로 나타났습니다.저장 프로시저의 변수와 비교했을 때 동일하지만, 비교할 때 사용한 에디터에서는 여분의 공간을 알아차리지 못했습니다.지난 4일 동안 제가 찾을 수 있는 모든 것을 시도하고 .net 오라클 드라이버까지 바꾸느라 저를 미치게 했습니다.다른 사람을 도울 수 있도록 여기에 버리고 싶었어요.우리는 캐릭터에 집중하고 공간을 무시하는 경향이 있습니다.

'for'라는 매개 변수를 하나의 Command에 입니다.즉, 동일한 이름의 매개 변수를 하나의 Oracle Command에 추가하는 것입니다.사용해야 합니다.cmd.Parameters.clear()매개 변수를 새로 고칩니다.

for(int i=0;i<usersList.Count;i++)
        {
            if (!(selectedUsersArray[i].Equals("")) && !passwordArray[i].Equals(""))
            {
                cmd.Parameters.clear();//Add this line
                OracleParameter userName = new OracleParameter();
                userName.ParameterName = "user";
                userName.Value = selectedUsersArray[i];

                OracleParameter passwd = new OracleParameter();
                passwd.ParameterName = "password";
                passwd.Value = passwordArray[i];

                cmd.Parameters.Add(userName);
                cmd.Parameters.Add(passwd);

                cmd.Prepare();
                cmd.ExecuteNonQuery();                   


            }
        } 

Oracle 오류 ORA-01036은 쿼리가 정의되지 않은 변수를 어딘가에서 사용한다는 것을 의미합니다.쿼리에서 사용 중인 변수, 즉 @로 시작하는 모든 변수를 확인할 수 있습니다.그러나 고급 조회에 입력하는 경우 Oracle 데이터베이스가 대소문자를 구분하는 경우 변수 이름과 동일한 대소문자를 포함하여 모든 변수에 일치하는 입력 매개 변수가 있는지 확인하는 것이 중요합니다.

는 이오는사가누경발우 도 류 생 니 합 다 에 된cmd.CommandType = System.Data.CommandType.StoredProcedure;

 cmd.Parameters.Add(new OracleParameter("GUSERID ", OracleType.VarChar)).Value = userId;

위의 "GUSERID" 코드에 표시된 것처럼 저는 8개의 매개 변수를 가지고 있었고 하나는 끝에 공백이 있었습니다.공간을 제거하고 모든 것이 작동하기 시작했습니다.

저는 환경을 준비하기 위한 모든 조정 중에서 제가 유지하고 있는 애플리케이션에서 동일한 문제를 겪고 있었습니다. 또한 애플리케이션 연결이 구식 데이터베이스를 가리킨다는 것을 알 때까지 거의 한 시간 동안 "ORA-01036: 불법 변수 이름/번호"라는 오류로 머리를 부딪쳤습니다.따라서 응용 프로그램은 오류를 유발하는 오래된 데이터베이스 절차에 두 개의 매개 변수를 더 전달했습니다.

매개 변수가 있는 pl/sql에는 사용자/테이블 이름을 전달할 수 없습니다.프로시저를 생성하고 sql을 빌드한 다음 즉시 실행하여 이를 달성할 수 있습니다.

저는 같은 문제에 직면했습니다...이와 같은 문제로, 나는 PRC inside cpp program과 나의 PRC에 4개의 인수를 요청하고 있지만, 호출하는 동안 1개의 인수만 사용하여 이 오류가 발생했습니다.

Begin Example_PRC(:1); End; // this cause the problem 
Begin Example_PRC(:1,:2,:3,:4); End; // this is the solution

오늘 파이썬 모듈을 사용할 때도 같은 문제가 있었습니다.cx_Oracle제 경우, 근본 원인은 잘못된 변수 이름이었습니다.

예:SELECT * FROM DATA WHERE KEY IN (:_0, :_1, ...)

내가 변했을 때_0로.var0그것은 잘 작동했습니다.

이 블로그 게시물에서 변수 이름에 대한 다음 규칙을 찾았습니다.

  • 문자로 시작해야 함
  • 최대 크기는 30자로 제한됩니다.
  • 공백 문자를 포함할 수 없습니다.
  • 달러 기호('$'), 밑줄('_') 및 해시 기호('#')를 포함할 수 있습니다.
  • 대소문자 구분 안 함

저도 같은 문제를 겪었습니다. 오라클레브와의 연결을 배우고 있었습니다.이전 코드

SELECTALLCANDIDATES = "Select * from candidate_master";
data= await connection.execute(SELECTALLCANDIDATES, {autoCommit:true})

제거했습니다.{autoCommit:true}그리고 잘 작동하기 시작했습니다.
정확한 코드

SELECTALLCANDIDATES = "Select * from candidate_master";
data= await connection.execute(SELECTALLCANDIDATES)

왜 그런지는 모르겠지만 효과가 있습니다.

by @stefan.sc hetschke에 이미 언급된 요점에 추가하고 싶을 뿐입니다.현재 Oracle은 "select" 쿼리를 사용하는 execute many()를 지원하지 않습니다.

오류가 발생하는 코드 조각의 예는 다음과 같습니다.

sql = """
    SELECT *
    FROM TABLE1
    WHERE 
        col1 = :cd
"""
data = [{'cd' : 1}, {'cd': 2}, {'cd': 3}]

cur.executemany(sql, data)


    

명명된 변수가 일치하는지 확인하십시오. 동일한 문제가 발생했습니다. 매개 변수 중 하나에 철자 오류/입력 오류가 있습니다.

언급URL : https://stackoverflow.com/questions/21375288/ora-01036-illegal-variable-name-number-when-running-query-through-c-sharp

반응형