我收到一条错误消息:使用以下代码请求未实现或不合理的转换:
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。
任何想法都非常苛刻!
更新 此代码有效:
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;
答案 0 :(得分:4)
一些问题,猜测和建议......
TABLE_PART_NUM.FAMILY
的确切DDL SQL类型是什么?
您是否尝试使用OdbcType.VarChar
,OdbcType.NVarChar
甚至OdbcType.NText
代替OdbcType.Text
?
此外,请注意,默认情况下,NVARCHAR2大小以字符为单位,但VARCHAR2以字节为单位 - 可能" 4000"在您的代码中被解释为4000 字符,超过了4000 字节的字符数据的最大字段宽度。尝试使用2000甚至更低的数字仅用于测试目的。
尝试从SQL Developer执行查询。你有什么问题吗?
你使用任何"不寻常的"数据库中的字符编码?你可以执行......
SELECT * FROM NLS_DATABASE_PARAMETERS WHERE PARAMETER LIKE '%CHARACTERSET';
...并查看NLS_CHARACTERSET
的VARCHAR2编码和NLS_NCHAR_CHARACTERSET
的NVARCHAR2编码。
您的ODBC驱动程序和Oracle服务器的确切版本是什么?他们匹配吗?
如果尝试使用等效的ODP.NET代码,是否会出现此问题?
答案 1 :(得分:0)
我怀疑这是因为你正在使用它:
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 > ?
答案 2 :(得分:0)
使用以下示例代码。你需要创建临时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();
}