确定Oracle列由序列和​​触发器填充(标识列如SQLServer)

时间:2013-09-17 06:28:32

标签: c# oracle getschematable

如果列自动填满,我必须确定。

这主要是在PrimaryKey Columns完成的。 这必须使用Oracle数据库以及SQLServer来完成。

我的问题的背景是(仅为了您更好的理解),我正在阅读规范所说的XML文件,元素标签与表的列名相匹配。 该表将由用户提供,他选择我必须解析的xml文件。 之后,我正在寻找xml文件中的所有元素,如果它们匹配表中列的名称。

目前尚不清楚xml文件是否会提供主键信息。 它可能是,但也可能不是。如果列的名称将在xml中,那么一切都会好的。 但如果没有,我必须查看是否

  • 我在xml文件中给出了一个PK列,也是
  • 如果该PK列自动填充值

如果没有给出,我必须提出异常。 因此我必须确定架构信息。

使用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();
                }
            }

1 个答案:

答案 0 :(得分:2)

简答:如果按顺序更新列,则无法通过架构信息判断。

您使用的Oracle版本可能没有Identity列的概念。该功能通常通过表格上的序列和触发器进行复制。

在Oracle DB中,序列不依赖于特定列。任何给定的序列都可用于获取要插入所需任何数字列的值。该序列可以在许多地方使用......触发器,程序,函数,单独的应用程序代码等。

我认为解析触发器的主体是一种选择。如果您只关心通过触发器更新列,那么这是可行的。

这可能是一个糟糕的建议,但是如果您确定数据库中的命名约定,那么可能做出一些假设,例如在序列名中引用表和/或列名。然而,虽然Oracle中存在令人讨厌的30个字符名称限制,但很容易破坏这些假设。