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

本文关键字:标识 SQLServer 触发器 Oracle 确定 填充 | 更新日期: 2023-09-27 18:31:46

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

大多数情况下,这是在 PrimaryKey 列中完成的。这必须使用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 那样在列中声明列,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();
                }
            }

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

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

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

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

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

这可能是一个不好的建议,但如果你确定数据库中的命名约定,你可能会做出一些假设,比如在序列名称中引用表和/或列名。话又说回来,尽管甲骨文中有一个讨厌的 30 个字符名称限制,可以很容易地打破这些假设。