Informix 到 Oracle:处理获取空值
首先介绍一下背景。 我的公司正在评估是否将 Informix 数据库迁移到 Oracle 10g。 我们有几个 ESQL/C 程序。 我已经通过 Oracle 迁移工作台运行了一些,并且一直在进行一些测试。 现在我开始意识到一些事情。
首先,我们有根本不处理空值的动态 SQL 语句。 根据我的阅读,我要么必须手动修改查询以利用 nvl() 函数,要么实现指示符变量。 有人可以确认是否需要手动修改吗? 我们对转换后的 ESQL/C 程序进行的手动更改越少越好。
其次,我们有几个查询从不同的表等中提取日期,并且在 Informix 中,日期被视为 long 类型,即自 1899 年 12 月 31 日以来的天数。
在 Pro*C 中,选择的日期是什么格式? 我知道它不是数字,因为我尝试将日期字段选择到我的长变量中,并收到 Oracle 错误,指出“预期数字但得到日期”。 因此,我假设我们必须修改选择日期字段的方式 - 要么以转换的方式选择日期字段,使其变得很长(即自 1899 年 12 月 31 日以来的天数),要么更改主机变量来匹配 Oracle 返回的内容(那是什么,字符串?)。
A bit of background first. My company is evaluating whether or not we will migrate our Informix database to Oracle 10g. We have several ESQL/C programs. I've run some through the Oracle Migration workbench and have been muddling through some testing. Now I've come to realize a few things.
First, we have dynamic sql statements that are not handling null values at all. From what I've read, I either have to manually modify the queries to utilize the nvl( ) function or implement indicator variables. Can someone confirm if manual modifications are necessary? The least amount of manual changes we have to make to our converted ESQL/C programs, the better.
Second, we have several queries which pull dates from various tables etc., and in Informix dates are treated as type long, the # of days since Dec 31st, 1899.
In Pro*C, what format is a date being selected as? I know it's not numeric because I tried selecting date field into my long variable and get Oracle error stating "expected NUMBER but got a DATE". So I'm assuming we'd have to modify how we are selecting date fields - either select a date field in a converted manner so it becomes a long (ie, # of days since 12/31/1899), or change the host variable to match what Oracle is returning (what is that, string?).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
是啊。 您将需要按照您的描述修改您的查询。
长让你绊倒。 long 在 Oracle 中具有不同的含义。 有一个特定的 DATE 类型。 通常,在选择一个时,请使用具有某种格式的 TO_DATE 函数,以获得 VARCHAR2 形式的结果,其格式正是您想要的。
Ya. You will need to modify your queries as you described.
long is tripping you up. long has a different meaning in Oracle. There is a specific DATE type. Generally when selecting one uses the TO_DATE function with a format, to get the result as a VARCHAR2, in exactly the format you want.
您可能还没有意识到,但请注意,在 Oracle 中,空的 VARCHAR2 字段是 NULL。 我看不出这背后有什么逻辑(可能是因为我来自 Informix)——记住这一点即可。 我认为这是愚蠢的 - 恕我直言,空字符串是有意义的并且与 NULL 不同。
将所有 VARCHAR2 字段修改为
NOT NULL DEFAULT '-'
或任何其他任意值,或者在返回 VARCHAR2 字段的所有查询中使用指示符,或者始终使用NVL().
Probably it didn't hit you yet but be aware that in Oracle empty VARCHAR2 fields are NULLs. I see no logic behind this (probably because I came from Informix land) - just keep it in mind. I think it is stupid - IMHO empty string is meaningful and different from NULL.
Either modify all your VARCHAR2 fields to be
NOT NULL DEFAULT '-'
or any other arbitrary value, or use indicatores in ALL your queries that return VARCHAR2 fields, or always useNVL()
.为了将 Oracle 日期(以 Oracle 内部格式存储)转换为长整数,您需要更改查询。 使用以下公式计算日期:
Oracle 系统“J”(儒略日期)格式是自公元前 4712 年 12 月 31 日以来的天数计数。 如果您想从较晚的日期开始计数,则需要减去该较晚日期的儒略日计数。
一个建议:不要改变程序中的所有查询(这可能会产生问题并引入错误),而是在不同的模式中创建一组视图。 这些视图的名称与所有表相同,具有相同的列,但包含 NVL() 和 date() 公式(如上)。 然后将您的应用程序指向视图模式而不是基表模式。 测试更少,遗漏的地方也更少。
例如,将所有表放入名为“APPS_BASE”的模式(由用户“APPS_BASE”定义)。然后创建另一个名为“APPS_VIEWS”的模式/用户。在 APPS_VIEWS 中创建一个视图:
In order to convert the oracle dates (which are store in Oracle internal format) into a long integer, you will need to alter your queries. Use the following formula for your dates:
The Oracle system 'J' (for Julian date) format is a count of number of days since December 31, 4712BC. If you want to count from a later date, you'll need to subtract off the Julian day count of that later date.
One suggestion: instead of altering all of your queries in your programs (which may create problems and introduce bugs), create a set of views in a different schema. These views would be named the same as all the tables, with all the same columns, but include the NVL() and date() formulas (like above). Then point your application at the view schema rather than the base table schema. Much less testing and fewer places to missing something.
So for example, put all your tables into a schema called "APPS_BASE" (defined by the user "APPS_BASE". Then create another schema/user called "APPS_VIEWS". In the APPS_VIEWS create a view: