База данных Oracle - ORA-01460 - запрошено невыполненное или необоснованное преобразование - PullRequest
5 голосов
/ 15 ноября 2011

Я получаю сообщение об ошибке: нереализованное или необоснованное преобразование запрошено с использованием следующего кода:

OdbcConnection oConn = new OdbcConnection();
oConn.ConnectionString = @"Driver={Oracle ODBC Driver};Data Source=*****;UID=********;PWD=******;DBQ=*****;DBA=R;APA=T;FEN=T;QTO=F;FRC=10;FDL=10;LOB=F;RST=T;FRL=T;MTS=F;CSR=F;PFC=10;TLO=0;";

oConn.Open();

string user = "ANYUSER";
string family = "ANYFAMILY";
DateTime date = DateTime.Today;

OdbcCommand FindCases = new OdbcCommand(@"select TABLE_CASE.ID_NUMBER, TABLE_USER.LOGIN_NAME
                                          from TABLE_CASE, TABLE_USER, TABLE_PRIVCLASS, TABLE_CONDITION, TABLE_PART_NUM
                                          where TABLE_CASE.CASE_ORIGINATOR2USER=TABLE_USER.OBJID and TABLE_CASE.CASE_STATE2CONDITION=TABLE_CONDITION.OBJID and TABLE_CASE.CASE_PRT2PART_INFO=TABLE_PART_NUM.OBJID
                                          and TABLE_USER.USER_ACCESS2PRIVCLASS=TABLE_PRIVCLASS.OBJID and TABLE_USER.LOGIN_NAME=? and TABLE_PART_NUM.FAMILY=? and TABLE_CONDITION.S_TITLE='CLOSED' and TABLE_CASE.CREATION_TIME > to_date(?,'MM/DD/YYYY HH:MI:SS AM')", oConn);

FindCases.CommandType = System.Data.CommandType.Text;
FindCases.Parameters.Add(@"user", OdbcType.Text, 4000).Value = user;
FindCases.Parameters.Add(@"family", OdbcType.Text, 4000).Value = family;
FindCases.Parameters.Add(@"date", OdbcType.DateTime, 4000).Value = date;

if (oConn.State == System.Data.ConnectionState.Open)
{
     try
     {
         OdbcDataReader readCases = FindCases.ExecuteReader(); //errors at this line

Я посмотрел в Интернете, и единственное предложение, которое я смог найти, было использование оператора to_clob.Либо я не понимаю, как это работает, либо это не решает проблему.Насколько мне известно, не должно быть никакого покрытия типов данных.Поле 'user' - это текст, поле 'family' - это текст, а поле 'date' - это DateTime в базе данных.

Любые идеи очень ценятся!

UPDATE Этот код работает:

OdbcCommand FindCases = new OdbcCommand(@"select TABLE_CASE.ID_NUMBER, TABLE_USER.LOGIN_NAME
                                                    from TABLE_CASE, TABLE_USER, TABLE_PRIVCLASS, TABLE_CONDITION, TABLE_PART_NUM
                                                    where TABLE_CASE.CASE_ORIGINATOR2USER=TABLE_USER.OBJID and TABLE_CASE.CASE_STATE2CONDITION=TABLE_CONDITION.OBJID and TABLE_CASE.CASE_PRT2PART_INFO=TABLE_PART_NUM.OBJID
                                                    and TABLE_USER.USER_ACCESS2PRIVCLASS=TABLE_PRIVCLASS.OBJID and TABLE_USER.LOGIN_NAME=? and TABLE_PART_NUM.FAMILY='Desktop' and TABLE_CONDITION.S_TITLE='CLOSED' and TABLE_CASE.CREATION_TIME > ?", oConn);

        FindCases.CommandType = System.Data.CommandType.Text;
        FindCases.Parameters.Add(@"user", OdbcType.Text, 4000).Value = user;
        //FindCases.Parameters.Add(@"family", OdbcType.Text, 4000).Value = family;
        FindCases.Parameters.Add(@"date", OdbcType.DateTime, 4000).Value = date;

ОБНОВЛЕНИЕ (СНОВА)

Этот код также отлично работает, хотя и уязвим для внедрения SQL.

        OdbcCommand FindCases = new OdbcCommand(@"select TABLE_CASE.ID_NUMBER
                                                    from TABLE_CASE, TABLE_USER, TABLE_PRIVCLASS, TABLE_CONDITION, TABLE_PART_NUM
                                                    where TABLE_CASE.CASE_ORIGINATOR2USER=TABLE_USER.OBJID and TABLE_CASE.CASE_STATE2CONDITION=TABLE_CONDITION.OBJID and TABLE_CASE.CASE_PRT2PART_INFO=TABLE_PART_NUM.OBJID
                                                    and TABLE_USER.USER_ACCESS2PRIVCLASS=TABLE_PRIVCLASS.OBJID and TABLE_USER.LOGIN_NAME=? and TABLE_PART_NUM.FAMILY='" + family + "' and TABLE_CONDITION.S_TITLE='CLOSED' and TABLE_CASE.CREATION_TIME > ?", oConn);

        FindCases.CommandType = System.Data.CommandType.Text;
        FindCases.Parameters.Add(@"user", OdbcType.Text, 4000).Value = user; //field size 30, text
        //FindCases.Parameters.Add(@"family", OdbcType.Text, 4000).Value = family; //field size 20, text
        FindCases.Parameters.Add(@"date", OdbcType.DateTime, 4000).Value = date;

РЕШЕНИЕ

Я не осознавал, что «текст» не является истинным типом.Переход на NVARCHAR сделал свое дело:

        OdbcCommand FindCases = new OdbcCommand(@"select TABLE_CASE.ID_NUMBER
                                                    from TABLE_CASE, TABLE_USER, TABLE_CONDITION, TABLE_PART_NUM
                                                    where TABLE_CASE.CASE_ORIGINATOR2USER=TABLE_USER.OBJID and TABLE_CASE.CASE_STATE2CONDITION=TABLE_CONDITION.OBJID and TABLE_CASE.CASE_PRT2PART_INFO=TABLE_PART_NUM.OBJID
                                                    and TABLE_USER.LOGIN_NAME=? and TABLE_PART_NUM.FAMILY=? and TABLE_CONDITION.S_TITLE='CLOSED' and TABLE_CASE.CREATION_TIME > ?", oConn);

        FindCases.CommandType = System.Data.CommandType.Text;
        FindCases.Parameters.Add(@"user", OdbcType.NVarChar, 30).Value = user; //field size 30, text
        FindCases.Parameters.Add(@"family", OdbcType.NVarChar, 20).Value = family; //field size 20, text
        FindCases.Parameters.Add(@"date", OdbcType.DateTime, 4000).Value = date;

Ответы [ 3 ]

4 голосов
/ 15 ноября 2011

Некоторые вопросы, догадки и предложения ...

Каков точный тип DDL SQL для TABLE_PART_NUM.FAMILY?

Вы пытались использовать OdbcType.VarChar, OdbcType.NVarChar или даже OdbcType.NText вместо OdbcType.Text?

Также обратите внимание, что по умолчанию размер NVARCHAR2 указан в символах, а VARCHAR2 - вбайт - возможно, «4000» в вашем коде интерпретируется как 4000 символов , что превышает максимальную ширину поля для символьных данных 4000 байтов .Попробуйте использовать 2000 или даже меньшее число только для целей тестирования.

Попробуйте выполнить запрос от разработчика SQL.У вас есть какие-нибудь проблемы?

Используете ли вы какую-нибудь "необычную" кодировку символов в вашей базе данных?Вы можете выполнить ...

SELECT * FROM NLS_DATABASE_PARAMETERS WHERE PARAMETER LIKE '%CHARACTERSET';

... и посмотреть NLS_CHARACTERSET для кодировки VARCHAR2 и NLS_NCHAR_CHARACTERSET для кодировки NVARCHAR2.

Каковы точные версии вашего драйвера ODBCа сервер Oracle?Они совпадают?

Возникает ли эта проблема, если вы пытаетесь использовать эквивалентный код ODP.NET?

0 голосов
/ 06 января 2014

Используйте приведенный ниже пример кода.вам нужно создать временный LOB.это работает для меня

using System.Data.OracleClient;

OracleConnection objConnection = new OracleConnection();
OracleCommand objCommand = new OracleCommand();
try
{
    objConnection.ConnectionString = System.Configuration.ConfigurationManager.AppSettings["YourConnectionString"].ToString();

    if (objConnection.State != System.Data.ConnectionState.Open)
    {
        objConnection.Open();
    }

    objCommand.Connection = objConnection;

    //Create Temporary LOB @Start
    //Error Without Temp LOB { ORA-01460: unimplemented or unreasonable conversion requested }
    objCommand.CommandText = "DECLARE dpBlob BLOB; BEGIN DBMS_LOB.CREATETEMPORARY(dpBlob, False, 0); :tmpBlob := dpBlob; END;";
    objCommand.Parameters.Add(new OracleParameter("tmpBlob", OracleType.Blob)).Direction = System.Data.ParameterDirection.Output;
    objCommand.ExecuteNonQuery();
    OracleLob tempLob = default(OracleLob);
    tempLob = (OracleLob)objCommand.Parameters[0].Value;
    tempLob.BeginBatch(OracleLobOpenMode.ReadWrite);
    tempLob.EndBatch();
    objCommand.Parameters.Clear();
    //Create Temporary LOB @End

    objCommand.CommandType = System.Data.CommandType.StoredProcedure;
    objCommand.CommandText = "INSERT_BLOB";

    objCommand.Parameters.AddWithValue("IN_USERNAME", "Sample Name");
    objCommand.Parameters.AddWithValue("IN_UPLOADED_BY", "Sample Name");

    string excelFileName = FileUpload1.PostedFile.FileName;
    int intlength = FileUpload1.PostedFile.ContentLength;

    Byte[] byteData = new Byte[intlength];
    FileUpload1.PostedFile.InputStream.Read(byteData, 0, intlength);

    objCommand.Parameters.AddWithValue("IN_ATTACH_FILE_ORIGINAL", excelFileName);
    objCommand.Parameters.Add("IN_ATTACH_BLOB_ORIGINAL", OracleType.Blob).Value = tempLob;

    objCommand.ExecuteNonQuery();

}
catch (Exception ex)
{
}
finally
{
    objCommand.Parameters.Clear();
    if (objConnection.State != System.Data.ConnectionState.Closed)
        objConnection.Close();
}
0 голосов
/ 15 ноября 2011

I подозреваю это потому, что вы используете это:

TABLE_CASE.CREATION_TIME > to_date(?,'MM/DD/YYYY HH:MI:SS AM')

, который ожидает параметр string , но вы уже передаете DateTime значение:

FindCases.Parameters.Add(@"date", OdbcType.DateTime, 4000).Value = date;

Я подозреваю, что вы можете просто изменить свой SQL для использования:

TABLE_CASE.CREATION_TIME > ?
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...