【问题标题】:Determining Oracle Column gets filled by sequence and trigger (Identity Column like SQLServer)确定 Oracle 列由序列和​​触发器填充(如 SQLServer 的标识列)
【发布时间】:2013-09-17 06:28:31
【问题描述】:

我必须确定一列是否自动填满。

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

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

不清楚xml文件是否会给我主键信息。 可能是,但也不可能。如果列的名称将在 xml 中,一切都会好起来的。 但是如果没有,我必须查一下如果

  • 我在 xml 文件中给出了一个 PK 列,并且还有
  • 如果该 PK 列自动填充了值

如果没有给出,我必须提出一个例外。 因此,我必须确定该架构信息。

使用 SQLServer 没有问题。 IsAutoIncrement 将为真,如果它是一个标识列。

我是这样读取表模式数据的(只是一个简短的例子)

System.Data.Common.DbDataReader reader = command.ExecuteReader(CommandBehavior.KeyInfo);
dtTable = reader.GetSchemaTable();

现在我得到了我想要的所有信息。 不幸的是,对于 Oracle,IsAutoIncrement 属性设置为 false。

我知道,如果 DBMS 没有像 SQLServer 那样在 Column 中声明,GetSchemaTable() 应该如何确定该列是否由序列设置。 这对我来说很清楚。

有人知道如何解决这个问题吗? 确定表中的列是否被触发器内的序列填充? 也许解析触发器主体?

提前感谢您的帮助

我的解决方案现在看起来像这样:

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

【问题讨论】:

    标签: c# oracle getschematable


    【解决方案1】:

    简短回答:您无法从架构信息中判断列是否由序列更新。

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

    在 Oracle DB 中,序列不绑定到特定列。任何给定的序列都可用于获取要插入到您想要的任何数字列中的值。该序列可以在很多地方使用...触发器、过程、函数、单独的应用程序代码等。

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

    这可能是个坏建议,但如果您确定数据库中的命名约定,您可以也许做出一些假设,例如在序列名称中引用了表和/或列名称。再说一次,尽管 Oracle 中有 30 个字符的名称限制很容易打破这些假设。

    【讨论】:

    • 我也是这么想的。我现在考虑选择 all_trigger_cols 并在 Column_Name 中查找我的 PK 列。据我所知,我们在 oracle 中的数据库环境仅使用触发器按顺序设置 PK 信息。没有其他用途。所以我想,我也可以像这样解决它。由于缺少声誉,我不太可能对你投赞成票:(
    • 没问题:)。祝你好运!
    • 随着我的名声有所增长,在这里你应得的投票:)
    猜你喜欢
    • 2014-05-05
    • 2017-07-28
    • 2015-03-04
    • 2012-11-05
    • 1970-01-01
    • 1970-01-01
    • 2013-07-19
    • 2014-10-28
    • 1970-01-01
    相关资源
    最近更新 更多