Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Oracle数据库-ORA-01460-未实现或请求的转换不合理_C#_Oracle - Fatal编程技术网

C# Oracle数据库-ORA-01460-未实现或请求的转换不合理

C# Oracle数据库-ORA-01460-未实现或请求的转换不合理,c#,oracle,C#,Oracle,我收到一条错误消息:使用以下代码请求的转换未实现或不合理: 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;

我收到一条错误消息:使用以下代码请求的转换未实现或不合理:

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语句。要么我不明白它是如何工作的,要么这不能解决问题。据我所知,不应该有任何数据类型的转换。“用户”字段是文本,“家庭”字段是文本,“日期”字段是数据库中的日期时间

任何想法都是非常宝贵的

更新 此代码适用于:

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;
我怀疑是因为你在用这个:

TABLE_CASE.CREATION_TIME > to_date(?,'MM/DD/YYYY HH:MI:SS AM')
它需要一个字符串参数,但您已经传入了一个
DateTime
值:

FindCases.Parameters.Add(@"date", OdbcType.DateTime, 4000).Value = date;
我想您可以将SQL更改为使用:

TABLE_CASE.CREATION_TIME > ?
一些问题、猜测和建议

表的确切DDL SQL类型是什么

您是否尝试使用
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\u CHARACTERSET
了解VARCHAR2编码,查看
NLS\u NCHAR\u CHARACTERSET
了解NVARCHAR2编码

ODBC驱动程序和Oracle服务器的确切版本是什么?他们匹配吗


如果您尝试使用等效的ODP.NET代码,是否会遇到此问题?

请使用下面的示例代码。您需要创建临时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();
}

谢谢你的回复。我不走运地尝试了你的建议。我尝试过“TABLE_CASE.CREATION_TIME>?”以及使用我的原始语句,但将类型更改为文本:@DarkShadow:您不应该进行任何不需要的字符串转换-因此我建议的更改应该是您的最佳选择,依我看。您说您尝试过它“没有运气”-这是否意味着您得到了相同的例外?是的,当我改为:TABLE_CASE.CREATION_TIME>时,仍然会遇到同样的异常?@DarkShadow:我认为只使用
CREATION_TIME
执行一个查询是值得的,以便检查这是否真的是导致问题的参数-基本上,将事情简化,直到得到最简单的查询来证明问题,这样就更容易尝试其他选择。什么类型的创作时间?谢谢你的帮助。。。日期似乎还可以。我尝试了相同的查询,但为family输入了一个静态值,它就工作了。必须与家族1有关,但我不知道是什么。我取出“家族”变量,用我正在寻找的家族中的一个来替换它,它按预期运行。我输入该家族变量的方式一定有问题,但我不知道会有什么问题。失败的示例有
family=“ANYFAMILY”
,成功的示例有
family='Desktop'
。如果问题取决于查询找到的记录,那么在这两种方法中尝试相同的族可能是值得的。(Oracle通常对某些值执行隐式强制转换,但对其他值不起作用。例如,只要字符串可以转换为数字,将数字与字符串进行比较就可以正常工作,但如果不能转换,则会中断。)