Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 在Oracle中从一个表插入到另一个表时,是否将多个VARCHAR字段合并为一个日期?_Sql_Oracle_Sql Insert_Toad_Oracle12c - Fatal编程技术网

Sql 在Oracle中从一个表插入到另一个表时,是否将多个VARCHAR字段合并为一个日期?

Sql 在Oracle中从一个表插入到另一个表时,是否将多个VARCHAR字段合并为一个日期?,sql,oracle,sql-insert,toad,oracle12c,Sql,Oracle,Sql Insert,Toad,Oracle12c,我正在尝试创建一个简短的脚本,它将从表1中获取所有字段并将它们插入表2中。基本字段(col1、col2、col3等)由以下内容覆盖: INSERT INTO Table1 (col1, col2, col3, col4, col5, col6, col7) SELECT col1, col2, col3, col4, col5, SYSDATE, USER FROM Table2 对于表1中的col8和col9,我有点卡住了col8/col9是DATE数据类型,需要将

我正在尝试创建一个简短的脚本,它将从表1中获取所有字段并将它们插入表2中。基本字段(col1、col2、col3等)由以下内容覆盖:

INSERT INTO Table1 (col1, col2, col3, col4, col5, col6, col7)
             SELECT col1, col2, col3, col4, col5, SYSDATE, USER
FROM Table2
对于表1中的
col8
col9
,我有点卡住了<例如,code>col8/col9是
DATE
数据类型,需要将表1中的
col6/col7/col8
col9/col10/col11
分别组合在一起插入。其中每一项的定义如下:

col6/col9  -- VARCHAR2 (2Byte) // Month
col7/col10 -- VARCHAR2 (2Byte) // Day
col8/col11 -- VARCHAR2 (4Byte) // Year
在网上查看时,我尝试了以下操作,但收到了“无效月份”:


有人知道如何得到我想要的,并将3个特定的VARCHAR字段合并为表1中的1个字段作为插入日期吗?

我不能肯定这就是您遇到的问题,但当我运行

从dual中选择字符(1,'00')

输出在预期的
01
前面有一个额外的空间。我会将对
的调用包装为对
TRIM()
的调用,以删除任何此类空格

从dual中选择TRIM(到字符(1,'00');

我也注意到,你的连接不匹配你提供的格式掩码。你的格式掩码已经分离了<代码> /<代码>,但是你并没有把它连接到你的字符串中。你的输出最多是MdDyyyy 。考虑把它添加到你的连接中,或者改变你的掩码。< /P>

INSERT INTO Table1 (......) SELECT ...., TO_DATE(TO_CHAR(col6, 'FM00') || TO_CHAR(col7, 'FM00') || TO_CHAR(col8, 'FM9999'), 'MMDDYYYY'), ..... FROM Table 2

IMHO,这是一个帮助。您的日期格式字符串错误,而且也是字符格式。应该可以使用…

如果列中的无效值始终为零,如您在注释中所述,那么您可以使用固定值(虚拟日期,或者更合理地将新列保留为空),并使用case语句:

SELECT ...., CASE
    WHEN TRIM('0' FROM col6) IS NULL OR TRIM('0' FROM col7) IS NULL
      OR TRIM('0' FROM col8) IS NULL THEN NULL
    ELSE TO_DATE(LPAD(col6, 2, '0') || LPAD(col7, 2, '0') || LPAD(col8, 4, '0'),
      'MMDDYYYY')
  END, ...
修剪从值中删除零,然后检查是否还有剩余的内容,这将一次性捕获0和00(对于col8,捕获000和0000)

LPAD用零填充左边的值,因此,例如,值7将变为07-这很重要,因为您需要连接的值来匹配日期格式模型,如果没有前导零,您将得到非常混乱和无效的结果

请注意,我根本不使用TO_CHAR。因为源列已经是字符串,所以实际上您正在对一个数字进行隐式转换,然后再显式转换回一个字符串。使用FM修饰符或TRIM,将具有与LPAD相同的效果,但会做更多的工作

作为CTE中一些示例值的快速演示:

with t as (
  select '0' as col6, '0' as col7, '0' as col8 from dual
  union all select '00', '00', '0000' from dual
  union all select '08', '31', '2008' from dual
  union all select '7', '4', '2012' from dual
)
select col6, col7, col8,
  CASE
    WHEN TRIM('0' FROM col6) IS NULL OR TRIM('0' FROM col7) IS NULL
      OR TRIM('0' FROM col8) IS NULL THEN NULL
    ELSE TO_DATE(LPAD(col6, 2, '0') || LPAD(col7, 2, '0') || LPAD(col8, 4, '0'),
      'MMDDYYYY')
  END as my_date
from t;

COL6 COL7 COL8 MY_DATE  
---- ---- ---- ----------
0    0    0              
00   00   0000           
08   31   2008 2008-08-31
7    4    2012 2012-07-04

如果您有其他无效值,这仍然会被它们绊倒-例如,2000年9月31日,该月的天数是错误的。不清楚您的数据是否会出现这种情况。如果是,您可以编写一个函数来尝试转换传递的任何内容,如果由于任何原因无效,则会自动返回null。

代码>否t一个有效的月份
错误是由于您的数据造成的。我确信您的数据中会有一个月的0,或者可能为空。请使用coalesce并对您试图转换的值进行一些错误处理。@paqogomez,看起来您是正确的。有一些关于这些(2)的记录对于单个3个字段,使用
00/00/0000
的3列组合。我不熟悉
Coalesce
;您介意提供一个示例说明您的意思吗?我假设您指的是某种形式的检查
00/null
,如果是,则设置默认数据值?是的,但这取决于您的数据。Coalesce只是在一组值<代码> > CueSeCe(NULL,NULL,1, 2 NULL)< /CUTE >返回>代码> 1 < /COD>。这里需要发生的是,您需要擦除数据,因为00/00/0000永远不会是有效的日期。请考虑将原始数据更改为有效值,或限制查询。(在where子句中)到不包含无效数据的列。如果源列已经是字符串,为什么要使用
到\u char
?也许您只是想用零填充值,而不是将它们转换为数字并返回?@paqogomez,您有
“如果col6/col7/col8='00/00/0000'设置Table2.col16=01/01/2000”
?到目前为止,我仍然无法将3个字段合并以插入到1个字段。使用一些其他建议,我尝试了
到日期(到字符(到字符6,'FM00'))|到字符(到字符7,'FM00'))|到字符(到字符8,'FM9999'),'mmddy'))
但仍然得到
不是有效日期
。我会使用FM格式修饰符,而不是修剪,但效果是一样的。但是,源字段是字符串,所以我不确定OP为什么会调用_char…@HepC,我会尝试一下。@AlexPoole,说实话,在DB查询方面非常绿色,几乎没有经验与Oracle合作(到目前为止,我只做了很少的M$产品)。使用
to_char
仅仅来自我在一个稍有不同的线程中看到的一个示例。我尝试了
FM
修饰符,如下面的DartXKey示例,并在
to_char()的周围添加了
TRIM()
我仍然收到
无效月份
?--
截止日期(截止日期)(截止日期)(截止日期)(截止日期)(截止日期)(截止日期)(截止日期)(截止日期)(截止日期)(截止日期)(截止日期)(截止日期)(截止日期)(截止日期)(截止日期)(截止日期)(截止日期)(截止日期)(截止日期8,'FM9999'),'mmddyyyyyy')
以下仍然产生
ORA-01843:无效月份
截止日期(截止日期)| | TO_CHAR(col8,'FM9999'),'MMDDYYYY')
您确定col6在0和12之间吗?选择不同的值,以表示兴趣..或向_CHAR(最大值(abs(col6),12))添加类似..的内容..如果您想忽略这些错误..另一方面..在select子句中添加/*+rule*/hint命令oracle不要尝试cost base optimizator来探测源表中的数据查看我的数据,如果字符串的值
with t as (
  select '0' as col6, '0' as col7, '0' as col8 from dual
  union all select '00', '00', '0000' from dual
  union all select '08', '31', '2008' from dual
  union all select '7', '4', '2012' from dual
)
select col6, col7, col8,
  CASE
    WHEN TRIM('0' FROM col6) IS NULL OR TRIM('0' FROM col7) IS NULL
      OR TRIM('0' FROM col8) IS NULL THEN NULL
    ELSE TO_DATE(LPAD(col6, 2, '0') || LPAD(col7, 2, '0') || LPAD(col8, 4, '0'),
      'MMDDYYYY')
  END as my_date
from t;

COL6 COL7 COL8 MY_DATE  
---- ---- ---- ----------
0    0    0              
00   00   0000           
08   31   2008 2008-08-31
7    4    2012 2012-07-04