1

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

大多数情况下,这是在 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 没有在 Column 中声明该列,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();
                }
            }
4

1 回答 1

2

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

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

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

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

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

于 2013-09-17T07:17:40.423 回答