Sun*_*nil 1 oracle ado.net devart
我在Oracle ADO.Net提供程序(DevArt的dotConnect Universal)中使用以下代码.有趣的是,它有时会起作用,然后大多数时候它会抛出Devart.Data.Oracle.OracleException: ORA-01722: invalid number
string sql = "SELECT DISTINCT B.PRICE_TIER_KEY,b.label, a.INSERT_DATE AS PriceEffectiveDate,B.PROGRAM_KEY AS PRICE_PROGRAM_KEY FROM GHX_MEMBER_TIER A INNER JOIN VHA_INT_PRICE_TIER B ON A.SRC_ID_VALUE = B.PRICE_TIER_KEY WHERE RowNum <=100";
DbProviderFactory dpf = DbProviderFactories.GetFactory(System.Configuration.ConfigurationManager.ConnectionStrings["Con_ORA_DevArt"].ProviderName);
DbConnection conn = dpf.CreateConnection();
conn.ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["Con_ORA_DevArt"].ConnectionString;
DbCommand dbcmd = dpf.CreateCommand();
dbcmd.Connection = conn;
//dbcmd.Connection = uniConnection1;
dbcmd.CommandText = sql;
dbcmd.CommandType = CommandType.Text;
dbcmd.CommandTimeout = 0;
DataTable table = new DataTable();
try
{
System.Data.Common.DbDataAdapter da = dpf.CreateDataAdapter();
da.SelectCommand = dbcmd;
// Fill the DataTable.
da.Fill(table);
}
catch (Exception ex)
{
throw;
}
finally
{
if (conn != null && conn.State != ConnectionState.Closed)
{
conn.Close();
conn.Dispose();
}
if (dbcmd != null)
{
dbcmd.Dispose();
}
}
Run Code Online (Sandbox Code Playgroud)
ORA-01722是数据转换错误.当字符串包含非数字值时,我们尝试将字符串转换为数字时会发生这种情况.这可以通过TO_NUMBER()强制转换显式发生,也可以通过在JOIN或WHERE子句中使用不同数据类型的列隐式发生.
所以你现在可以看到你发布了所有错误的信息:重要的是数据结构和所涉及的表的内容.最容易出错的候选者是联接中的两列:SRC_ID_VALUE和PRICE_TIER_KEY.这些都是数字列还是两个字符串?如果一个是数字而另一个不是数字,那么字符串1是否只包含数字数据?
这很重要,因为Oracle会在尝试比较之前将字符串列强制转换为数字.
例如,如果table1有这个数据......
1234
10789
Run Code Online (Sandbox Code Playgroud)
...和table2有这个数据......
'1234'
'45o7'
Run Code Online (Sandbox Code Playgroud)
第一行将正常连接,但第二行将抛出ORA-01722并使查询脱轨.
解决这个问题的方法是使用TO_CHAR()将数字列转换为字符串.这将阻止Oracle使用该列上的任何索引.这可能与您的情况无关,因为您很可能只是在两个表上进行全表扫描,但它可能对更精确的查询很重要.
"我认为这是甲骨文的一个可怕特征."
将字符串转换为数字会更改排序顺序.这个 ...
'1','10','2','21','3'
......变成这个......
1,2,3,10,21
当然它不能使用原始索引.
有一个解决方法,但它有点涉及.
使用该函数构建基于函数的索引:
在GHX_MEMBER_TIER上创建索引src_id_num_fbi(is_a_number(SRC_ID_VALUE));
在查询中使用该函数:
... ON is_a_number(A.SRC_ID_VALUE)= B.PRICE_TIER_KEY
只有你可以决定这是否值得付出努力.
| 归档时间: |
|
| 查看次数: |
4057 次 |
| 最近记录: |