【问题标题】:how to get db2 without any appended values如何在没有任何附加值的情况下获取 db2
【发布时间】:2014-07-16 10:10:10
【问题描述】:
select rtrim(char(PKG_AGR_IDR)),rtrim(char(STA_DTE)) 
from test FETCH FIRST 10 ROW ONLY


"0010000010. 2014-03-14"
"0010000010. 2014-03-14"

我需要如下数据:

0010000010 2014-03-14

我打算编写一个脚本来执行 rtrim(char(fieldname)) 是否有任何函数组合,我可以使用这些函数为两个字段获得正确的输出。

【问题讨论】:

  • 请提供列的数据库定义。看起来您向我们展示了一个单列,其中包含引号作为其值的一部分,中间有一个 .dot 和一个空格,但您的示例 SELECT 暗示有两个不同的列。另外,系统的版本/发行版是什么?

标签: db2 db2-luw db2-connect db2-400


【解决方案1】:

为了更好地描述场景,人们可能会认为 OP 可能写得更像以下内容:

将包括一些关于正在做的事情的背景,这样以后的引用 [例如对 field_name] 的引用将被预先解释,而不必由审阅者凭直觉。

其目的是启用动态生成 SQL SELECT 语句,该语句将从指定 TABLE 的列中检索数据的字符表示。给定 DDL create table THE_SCHEMA.TEST ( PKG_AGR_IDR NUMERIC(10, 0), STA_DTE DATE ) 并给定以下 DML 用于使用样本行 insert into THE_SCHEMA.TEST VALUES(10000010. '2014-03-14') 填充该 TABLE,所需的是获得一个结果集 [仅限于前十行以进行测试],它将将 [THE_SCHEMA 中名为 TABLE 的 TABLE 的] 每一列的数据包含为 VARCHAR 数据,由以下查询生成,该查询将由存储在 SYSCOLUMNS 目录 VIEW 中的元数据生成:
select rtrim(char(PKG_AGR_IDR)),rtrim(char(STA_DTE))
from test
FETCH FIRST 10 ROW ONLY

从 SYSCOLUMNS 数据生成为 'RTRIM(CHAR(' CONCAT COLUMN_NAME CONCAT '))' 的单个表达式(如在前面提到的查询中看到的两次)在应用于列名时似乎无法提供理想的结果,而不管正在格式化的 COLUMN_NAME 的 DATA_TYPE 的值通过那个字符表达式。具体来说,例如,动态生成的查询select RTRIM(CHAR(PKG_AGR_IDR)), RTRIM(CHAR(STA_DTE)) from THE_SCHEMA.TEST FETCH FIRST 10 ROW ONLY 的结果会产生以下输出:

0010000010. 2014-03-14

但是预期\期望的输出是:

0010000010 2014-03-14

是否有任何像 RTRIM(CHAR(column_name)) 这样的表达式,它将对 TABLE 中的所有列起作用,以获取字符串形式的数据,无论列的数据类型如何,无论它们是数字还是 varchar还是日期?

即使有了更完整的场景描述\背景:

关于原始表达式的输出是什么的声明对于影响十进制到字符转换的 CHAR 标量是出乎意料的,至少对于 DB2 for i SQL 而言,其零刻度压缩十进制 (DECIMAL) 和分区十进制 (NUMERIC ) SQL 数据类型表示没有小数分隔符 [又名小数点] 尽管可选的 decimal-character 作为第二个参数。同样,CHAR 标量在从数字转换时省略前导零。因此,DB2 for i SQL 将获得字符串'10000010' 的结果,而不是'0010000010.''10000010.' 的结果

我想这个问题可能特定于 DB2 for Z 或 DB2 LUW,也许这个主题被错误地标记为 DB2 for i?或者可能存在 [n unstated] 担心 DB2 变体之间明显的不兼容性?然而,在阅读了文档后,所描述的结果似乎与记录的结果相反,所以我怀疑 OP 的实际问题可能是由于遇到了一个缺陷 [无论是未说明的 DB2 变体和正在使用的版本级别].?

我不希望有任何一个表达式可以执行每个 NUMERIC、VARCHAR 和 DATE [也不适用于每个 INTEGER、SMALLINT、NUMERIC、DECIMAL、VARCHAR和日期]。由于省略了小数点,DB2 for i SQL 可能是最符合要求的表达方式,但前导零总是被修剪http://www.ibm.com/support/knowledgecenter/ssw_ibm_i_72/db2/rbafzscachar.htm

... 不返回前导零。返回尾随零。如果 decimal-expression 的小数位数为零,则不返回十进制字符。 ...

DB2 LUW SQL 在前导零的主题上似乎至少有些不连贯,因为示例 6 表明没有,然后 示例 7 显示它们在那里,但是就像上面的文档参考一样,显然不应该有前导零字符http://www.ibm.com/support/knowledgecenter/SSEPGG_10.1.0/com.ibm.db2.luw.sql.ref.doc/doc/r0000777.html

...不包括前导零。包括尾随零。 ... 如果十进制表达式的小数位数为零,则不返回十进制字符。 ...

我没有研究 DB2 for Z 文档链接。

我希望解决方案需要使用 CASE 表达式,也许是 DATA_TYPE 值。这就是我编写类似代码的方式,尽管我只使用了 VARCHAR 转换标量并且没有进行任何修剪。然而,我对 CASE 的要求不是保持前导零字符,而是主要用于选择正确的十进制分隔符。并且因为第二个参数 decimal-character [for CHAR or VARCHAR] 对于 INTEGER 数字类型 [sqlcode -171 aka SQL0171] 是不允许的,因此 CASE 表达式仅用于数字仅使用附加到'VARCHAR(' concat 的以下表达式CASE WHEN DATA_TYPE IN ('INTEGER', 'SMALLINT', 'BIGINT') THEN ', ' concat DecSep concat ')' ELSE ')' 就可以充分解析类型,其中DecSep 是一个字符变量,其以逗号或句点作为所选的小数分隔符。然而,由于第二个参数 [对于 CHAR 或 VARCHAR] 特定于第一个参数的数据类型,因此字符和日期\时间数据类型有自己的 CASE 表达式 CASE WHEN DATA_TYPE IN ('DATE', 'TIME') THEN ', ' concat StdFmt concat ')' ELSE ')' 附加到 'VARCHAR(' concat ,其中 StdFmt 是三个-具有 ISO、USA、EUR 或 JIS 的标准格式规范之一的字符变量。

【讨论】:

  • 谢谢,这对我有帮助,当我使用来自 unix 的 DB2 客户端进行查询时,我能够删除输出中出现的垃圾字符。
【解决方案2】:

不知道你在问什么。去掉双引号?删除点? 您可以通过提供第一个和最后一个位置来执行 substr,并将这两个值连接起来。

select substr(trim(PKG_AGR_IDR), 2, 11) || ' ' ||  trim(char(STA_DTE))
from test FETCH FIRST 10 ROW ONLY

【讨论】:

  • 我想要的是在 db2 中有一个查询,使用它我可以仅使用字段名称将输出作为字符串或字符用于任何字段。如果我使用 trim(char(field_name)) 我会得到额外的“。”附加在字符串字段 PKG_AGR_IDR 的末尾,但是 trim(char(field_name)) 与 STA_DTE 一起工作正常,是否有任何类似 char(trim(field_name)) 的内容适用于表中的所有列,无论它们具有数字、varchar 还是日期数据。我尝试了 char(trim(date_field)) 但将数据作为 NULL 作为输出,我的日期为 yyyy-mm-dd 格式。任何帮助将不胜感激。
  • 我没有完全理解你的评论。但是,您似乎需要查询目录,以便检索数据类型,然后创建所需的输出。
猜你喜欢
  • 2022-10-07
  • 1970-01-01
  • 1970-01-01
  • 2021-02-22
  • 2015-10-13
  • 2012-09-09
  • 1970-01-01
  • 2017-04-05
  • 2020-08-12
相关资源
最近更新 更多