如果列自动填满,我必须确定。
这主要是在PrimaryKey Columns完成的。 这必须使用Oracle数据库以及SQLServer来完成。
我的问题的背景是(仅为了您更好的理解),我正在阅读规范所说的XML文件,元素标签与表的列名相匹配。 该表将由用户提供,他选择我必须解析的xml文件。 之后,我正在寻找xml文件中的所有元素,如果它们匹配表中列的名称。
目前尚不清楚xml文件是否会提供主键信息。 它可能是,但也可能不是。如果列的名称将在xml中,那么一切都会好的。 但如果没有,我必须查看是否
如果没有给出,我必须提出异常。 因此我必须确定架构信息。
使用SQLServer,没问题。 如果它是一个标识列,则IsAutoIncrement将为true。
我读了这样的表模式数据(只是简短的例子)
System.Data.Common.DbDataReader reader = command.ExecuteReader(CommandBehavior.KeyInfo);
dtTable = reader.GetSchemaTable();
现在我得到了我想要的所有信息。 不幸的是,IsAutoIncrement属性设置为false。
我知道,如果DBMS没有在DBMS中声明,GetSchemaTable()如何确定列是否由序列设置,如SQLServer所做的那样。 这对我来说很清楚。
有没有人有想法,如何解决这个问题? 确定表中的列是否被触发器内的序列填充? 也许正在解析触发器体?
提前感谢您提供任何帮助
我的解决方案现在看起来像这样:
if (IsOracleClient)
{
// reading Trigger Information
string sql = "select\n" +
" a.trigger_body\n" +
" from\n" +
" all_triggers a,\n" +
" all_trigger_cols b\n" +
" where\n" +
" a.table_name = '{0}'\n" +
" and b.table_name = a.table_name\n" +
" and b.column_name = '{1}'\n" +
" and a.trigger_name = b.trigger_name";
command.CommandText = String.Format(sql, this.Tabelle.ToUpper(), this.PrimaryKeyColumn.ColumnName.ToUpper());
using (System.Data.Common.DbDataReader reader = command.ExecuteReader())
{
if (reader.HasRows)
{
reader.Read();
string body = reader.GetString(0);
if (body.Contains("NEXTVAL"))
this.PrimaryKeyColumn.IsAutoIncrement = true;
}
reader.Close();
}
}
答案 0 :(得分:2)
简答:如果按顺序更新列,则无法通过架构信息判断。
您使用的Oracle版本可能没有Identity列的概念。该功能通常通过表格上的序列和触发器进行复制。
在Oracle DB中,序列不依赖于特定列。任何给定的序列都可用于获取要插入所需任何数字列的值。该序列可以在许多地方使用......触发器,程序,函数,单独的应用程序代码等。
我认为解析触发器的主体是一种选择。如果您只关心通过触发器更新列,那么这是可行的。
这可能是一个糟糕的建议,但是如果您确定数据库中的命名约定,那么可能做出一些假设,例如在序列名中引用表和/或列名。然而,虽然Oracle中存在令人讨厌的30个字符名称限制,但很容易破坏这些假设。