从 Oracle 表动态获取列名的最佳方法
我们正在使用一个提取器应用程序,它将数据从数据库导出到 csv 文件。基于某些条件变量,它从不同的表中提取数据,对于某些条件,我们必须使用 UNION ALL,因为必须从多个表中提取数据。因此,为了满足 UNION ALL 条件,我们使用 null 来匹配列数。
现在系统中的所有查询都是根据条件变量预先构建的。问题是每当表投影发生变化(即添加新列、修改现有列、删除列)时,我们都必须手动更改应用程序中的代码。
您能否提供一些建议,如何动态提取列名,以便表结构的任何更改都不需要更改代码?
我关心的是决定查询哪个表的条件。变量条件为 就像
- 如果条件为 A,则从 TableX 加载;
- 如果条件为 B,则从 TableA 和 TableY 加载。
我们必须知道我们需要从哪个表中获取数据。一旦我们知道了表,就可以直接从数据字典中查询列名。但还有一个条件,就是需要排除一些列,并且这些列对于每个表来说都是不同的。
我试图解决仅动态生成列表列的问题。但我的经理告诉我要在概念层面上提出解决方案,而不仅仅是修复。这是一个非常大的系统,提供者和消费者不断加载和使用数据。所以他想要通用的解决方案。
那么存储条件、表名、排除列的最佳方式是什么?一种方法是存储在数据库中。还有其他方法吗?如果是的话什么是最好的?因为在最终确定之前我必须至少给出一些想法。
谢谢,
We are using an extractor application that will export data from the database to csv files. Based on some condition variable it extracts data from different tables, and for some conditions we have to use UNION ALL as the data has to be extracted from more than one table. So to satisfy the UNION ALL condition we are using nulls to match the number of columns.
Right now all the queries in the system are pre-built based on the condition variable. The problem is whenever there is change in the table projection (i.e new column added, existing column modified, column dropped) we have to manually change the code in the application.
Can you please give some suggestions how to extract the column names dynamically so that any changes in the table structure do not require change in the code?
My concern is the condition that decides which table to query. The variable condition is
like
- if the condition is A, then load from TableX
- if the condition is B then load from TableA and TableY.
We must know from which table we need to get data. Once we know the table it is straightforward to query the column names from the data dictionary. But there is one more condition, which is that some columns need to be excluded, and these columns are different for each table.
I am trying to solve the problem only for dynamically generating the list columns. But my manager told me to make solution on the conceptual level rather than just fixing. This is a very big system with providers and consumers constantly loading and consuming data. So he wanted solution that can be general.
So what is the best way for storing condition, tablename, excluded columns? One way is storing in database. Are there any other ways? If yes what is the best? As I have to give at least a couple of ideas before finalizing.
Thanks,
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
像这样的简单查询可以帮助您了解 Oracle 中表的每个列名。
在您的代码中使用它:)
A simple query like this helps you to know each column name of a table in Oracle.
Use it in your code :)
好的,MNC,尝试一下大小(将其粘贴到新的控制台应用程序中):
我稍后会回来看看它是否合适。
Ok, MNC, try this for size (paste it into a new console app):
I'll get back in a bit to see if it fits or not.
因此,您真正想要的是设计一个用于构建动态查询的规则引擎。这不是一件小事。您提供的要求包括:
您没有提到的一些可能的要求:
我会将这些规则存储在数据库表中。因为它们是数据,而存储数据就是数据库的用途。 (除非您手头上已经有规则引擎。)
满足第一组要求,您需要三个表:
我使用复合主键只是因为在这种情况下使用它们更容易,例如运行影响分析;我不会推荐它用于常规应用程序。
我认为除了 RULE_TABLES 上的附加列之外,所有这些都是不言自明的。
Table_Query_Order
指定表在 UNION ALL 查询中出现的顺序;仅当您想要使用主表的列名称作为 CSV 文件中的标题时,这才重要。All_Columns_YN
指示查询是否可以写为 SELECT * 或者是否需要从数据字典和 RULE_EXCLUDED_COLUMNS 表中查询列名。No_of_padding_cols
是通过指定要添加到列列表末尾的 NULL 数量来匹配这些 UNION ALL 列中的投影的简单实现。我不会解决您未指定的那些要求,因为我不知道您是否关心它们。基本的事情是,你的老板要求的是一个单独的应用程序。请记住,除了用于生成查询的应用程序之外,您还需要一个用于维护规则的界面。
So what you are really after is designing a rule engine for building dynamic queries. This is no small undertaking. The requirements you have provided are:
Some possible requirements you don't mention:
col1, col2, null, col3
.I would store these rules in database tables. Because they are data and storing data is what databases are for. (Unless you already have a rules engine to hand.)
Taking the first set of requirements you need three tables:
I've used compound primary keys just because it's easier to work with them in this context e.g. running impact analyses; I wouldn't recommend it for regular applications.
I think all of these are self-explanatory except the additional columns on RULE_TABLES.
Table_Query_Order
specifies the order in which the tables appear in UNION ALL queries; this matters only if you want to use the column_names of the leading table as headings in the CSV file.All_Columns_YN
indicates whether the query can be written as SELECT * or whether you need to query the column names from the data dictionary and the RULE_EXCLUDED_COLUMNS table.No_of_padding_cols
is a simplistic implementation for matching projections in those UNION ALL columns, by specifying how many NULLs to add to the end of the column list.I'm not going to tackle those requirements you didn't specify because I don't know whether you care about them. The basic thing is, what your boss is asking for is an application in its own right. Remember that as well as an application for generating queries you're going to need an interface for maintaining the rules.
MNC,
如何预先创建一个包含应用程序过程中涉及的所有已知表的字典(无论组合如何 - 只是表的字典),该字典以表名为键。该字典的成员将是列名称的
IList
。这将允许您比较两个表中存在的列数dicTable[myVarTableName].Count
以及迭代dicTable[myVarTableName].value
以提取结果列名称。在本文的最后,您可以执行一些 linq 函数来确定列数最多的表,并相应地创建具有空值的结构。
希望这能给人深思。
MNC,
How about creating a dictionary of all the known tables involved in the application process up front (irrespective of the combinations - just a dictionary of the tables) which is keyed on tablename. the members of this dictionary would be a
IList<string>
of the column names. This would allow you to compare two tables on both the number of columns presentdicTable[myVarTableName].Count
as well as iterating round thedicTable[myVarTableName].value
to pull out the column names.At the end of the piece, you could do a little linq function to determine the table with the greatest number of columns and create the structure with nulls accordingly.
Hope this gives food for thought..