使用oracle在日期字段中插入时间段
我在oracle中有一个过程:使用oracle在日期字段中插入时间段,oracle,datetime,stored-procedures,Oracle,Datetime,Stored Procedures,我在oracle中有一个过程: CREATE OR REPLACE PROCEDURE ONE ( p_GUID IN ONE.GUID%TYPE, p_START_DATE IN ONE.START_DATE%TYPE, p_END_DATE IN ONE.END_DATE%TYPE, p_RETURN OUT INTEGER ) AS BEGIN INSERT INTO ONETABLE (GUID, START_DATE, END_
CREATE OR REPLACE
PROCEDURE ONE
(
p_GUID IN ONE.GUID%TYPE,
p_START_DATE IN ONE.START_DATE%TYPE,
p_END_DATE IN ONE.END_DATE%TYPE,
p_RETURN OUT INTEGER
)
AS
BEGIN
INSERT INTO ONETABLE (GUID, START_DATE, END_DATE)
VALUES (p_GUID, to_date(p_START_DATE, 'YYYY-MM-DD HH24:MI:SS'), to_date(p_END_DATE, 'YYYY-MM-DD HH24:MI:SS'));
COMMIT;
EXCEPTION
WHEN OTHERS THEN
p_RETURN:= 1;
END;
编辑,因为人们似乎说要尝试这个(这也不起作用,我尝试使用to_date(上面的示例)来尝试解决这个问题):
当从c#调用它时(例如使用DateTime.NOW),它会失败
仅当开始日期和结束日期的格式为2013年4月5日时,此选项才有效。但是我怎样才能得到输入和输入的时间呢
如果我替换
p_START_DATE, 'YYYY-MM-DD HH24:MI:SS'
与
这是可行的,但从c#调用过程时失败
此外,如果我从db客户端手动运行该过程,我仍然必须输入2013年4月5日,只有这样才能工作。我无法输入时间,因为如果我尝试输入,时间将失败
开始日期和结束日期是oracle数据库中的日期类型
--
根据我的尝试,我会收到不同的信息
据我调查,这似乎与此有关:
SELECT value FROM v$nls_parameters WHERE parameter ='NLS_DATE_FORMAT';
返回:
DD-MON-RR
NLS_LANGUAGE AMERICAN
NLS_TERRITORY AMERICA
NLS_CURRENCY $
NLS_ISO_CURRENCY AMERICA
NLS_NUMERIC_CHARACTERS .
NLS_CALENDAR GREGORIAN
NLS_DATE_FORMAT DD-MON-RR
NLS_DATE_LANGUAGE AMERICAN
NLS_SORT BINARY
NLS_TIME_FORMAT HH.MI.SSXFF AM
NLS_TIMESTAMP_FORMAT DD-MON-RR HH.MI.SSXFF AM
NLS_TIME_TZ_FORMAT HH.MI.SSXFF AM TZR
NLS_TIMESTAMP_TZ_FORMAT DD-MON-RR HH.MI.SSXFF AM TZR
NLS_DUAL_CURRENCY $
NLS_COMP BINARY
NLS_LENGTH_SEMANTICS BYTE
NLS_NCHAR_CONV_EXCP FALSE
我不能改变这一点,因为我不是db的所有者
--
那么如何在那里获得时间部分呢?
以下是完整的SQL:
select parameter, value from nls_session_parameters;
返回:
DD-MON-RR
NLS_LANGUAGE AMERICAN
NLS_TERRITORY AMERICA
NLS_CURRENCY $
NLS_ISO_CURRENCY AMERICA
NLS_NUMERIC_CHARACTERS .
NLS_CALENDAR GREGORIAN
NLS_DATE_FORMAT DD-MON-RR
NLS_DATE_LANGUAGE AMERICAN
NLS_SORT BINARY
NLS_TIME_FORMAT HH.MI.SSXFF AM
NLS_TIMESTAMP_FORMAT DD-MON-RR HH.MI.SSXFF AM
NLS_TIME_TZ_FORMAT HH.MI.SSXFF AM TZR
NLS_TIMESTAMP_TZ_FORMAT DD-MON-RR HH.MI.SSXFF AM TZR
NLS_DUAL_CURRENCY $
NLS_COMP BINARY
NLS_LENGTH_SEMANTICS BYTE
NLS_NCHAR_CONV_EXCP FALSE
由于您的列在oracle中的类型为
DATE
,因此插入错误
你不应该这样做
to_date(p_START_DATE, 'YYYY-MM-DD HH24:MI:SS')
相反,只需插入
INSERT INTO ONETABLE (GUID, START_DATE, END_DATE)
VALUES (p_GUID, p_START_DATE, p_END_DATE);
通过在日期上执行to_Date,您将强制从Date转换为char,然后再转换回Date。换句话说,您的字符串:
to_date(p_START_DATE, 'YYYY-MM-DD HH24:MI:SS')
被悄悄地转换为
to_date(to_char(p_START_DATE, NLS_DATE_FORMAT), 'YYYY-MM-DD HH24:MI:SS')
例如,在你的情况下,可能:
to_date(to_char(p_START_DATE, 'DD-MON-RR'), 'YYYY-MM-DD HH24:MI:SS')
由于您的函数输入是%TYPE(这很好),因此它们也是日期:
p_START_DATE IN ONE.START_DATE%TYPE
因此,当您将输入传递到要传递的函数时,请确保输入是日期类型而不是字符串
例如:
SQL> CREATE OR REPLACE PROCEDURE ONE
2 (
3 p_GUID IN ONETABLE.GUID%TYPE,
4 p_START_DATE IN ONETABLE.START_DATE%TYPE,
5 p_END_DATE IN ONETABLE.END_DATE%TYPE,
6 p_RETURN OUT INTEGER
7 )
8 AS
9 BEGIN
10 INSERT INTO ONETABLE (GUID, START_DATE, END_DATE)
11 VALUES (p_GUID, p_START_DATE, p_END_DATE);
12 COMMIT;
13 EXCEPTION
14 WHEN OTHERS THEN
15 p_RETURN:= 1;
16 END;
17 /
Procedure created.
SQL> var r number
SQL> exec ONE('abc', to_date('2013-05-13 12:13:14', 'YYYY-MM-DD HH24:MI:SS'), to_date('2013-05-14 01:13:14', 'YYYY-MM-DD HH24:MI:SS'), :r);
PL/SQL procedure successfully completed.
SQL> select * from onetable;
GUID START_DATE END_DATE
-------------------- ------------------ ------------------
abc 13-may-13 12:13:14 14-may-13 01:13:14
abc 13-may-13 12:13:14 14-may-13 01:13:14
与隐式转换相比:
SQL> CREATE OR REPLACE PROCEDURE ONE
2 (
3 p_GUID IN ONETABLE.GUID%TYPE,
4 p_START_DATE IN ONETABLE.START_DATE%TYPE,
5 p_END_DATE IN ONETABLE.END_DATE%TYPE,
6 p_RETURN OUT INTEGER
7 )
8 AS
9 BEGIN
10 INSERT INTO ONETABLE (GUID, START_DATE, END_DATE)
11 VALUES (p_GUID, to_date(p_START_DATE, 'YYYY-MM-DD HH24:MI:SS'), to_date(p_END_DATE, 'YYYY-MM-DD HH24:MI:SS'));
12 COMMIT;
13
14 END;
15 /
Procedure created.
SQL> alter session set nls_date_format='dd-mon-yy';
Session altered.
SQL> var r number
SQL> exec ONE('abc', to_date('2013-05-13 12:13:14', 'YYYY-MM-DD HH24:MI:SS'), to_date('2013-05-14 01:13:14', 'YYYY-MM-DD HH24:MI:SS'), :r);
PL/SQL procedure successfully completed.
SQL> alter session set nls_date_format='dd-mon-rrrr hh24:mi:ss';
Session altered.
SQL> select * from onetable;
GUID START_DATE END_DATE
-------------------- -------------------- --------------------
abc 13-may-0013 00:00:00 13-may-0014 00:00:00
存储了错误的日期..或使用了差异NLS设置:
SQL> alter session set nls_date_format='dd-mon';
Session altered.
SQL> var r number
SQL> exec ONE('abc', to_date('2013-05-13 12:13:14', 'YYYY-MM-DD HH24:MI:SS'), to_date('2013-05-14 01:13:14', 'YYYY-MM-DD HH24:MI:SS'), :r);
BEGIN ONE('abc', to_date('2013-05-13 12:13:14', 'YYYY-MM-DD HH24:MI:SS'), to_date('2013-05-14 01:13:14', 'YYYY-MM-DD HH24:MI:SS'), :r); END;
*
ERROR at line 1:
ORA-01858: a non-numeric character was found where a numeric was expected
ORA-06512: at "TEST.ONE", line 10
ORA-06512: at line 1
无需将函数转换为日期类型。已经是约会了。 只需插入传入参数的值:
INSERT INTO ONETABLE (GUID, START_DATE, END_DATE)
VALUES (p_GUID, p_START_DATE, p_END_DATE);
更新
但若上面的变量不起作用,并且您看到引发的错误,那个么必须在客户端检查存储过程参数定义。您能否验证客户端上的p\u START\u DATE
参数是否具有DateTime类型
更新2
客户端有错误。
尝试初始化日期参数,如下例所示:
OracleParameter p1 = new OracleParameter();
p1.DbType = DbType.DateTime;
p1.Value = System.DateTime.Now;
错误的原因可能是C#组件将参数视为字符串,并将其转换为默认OS格式的字符串,然后通过查询将其传递给Oracle。Oracle试图将该字符串解析为ONE
存储过程定义中指定的日期类型,但失败了,因为需要NLS\u date\u格式参数提供默认格式
更新3
注释中的@b0x0rz解释了错误的真正原因(返回类型错误)。无论如何,这是客户端错误…您可以更改会话日期格式吗?e、 g.更改会话集NLS_日期_格式='YYYY-MM-DD';可能是的。但这是唯一的方法吗?这可能有点像p_START_DATE被视为日期而不是日期时间。开始日期和结束日期的创建表定义是什么?正如我在回答中所说的,这是客户端错误。@b0x0rz祝贺您!您的代码正在工作!:)感谢您解释错误的真正原因。希望对某人有所帮助。是的,插入一个表(GUID、开始日期、结束日期)值(p_GUID、p_开始日期、p_结束日期);也不行。这是原作。我试着去约会,试图解决这个问题。c#显式发送DateTime.Now值作为DATE类型。顺便说一句,这是c#作为DATE类型发送的内容:inParamName=p#u START#u DATE;inParamValue=4/5/2013下午3:13:30;inParamName=p_结束日期;inParamValue=4/5/2013下午3:13:30;它不是发送什么,只是参数的可视化。问题不在Oracle方面,而是在将C#值转换为Oracle参数并将其传递到数据库之前发生的。@ThinkJet是。正如我所说的,如果我尝试在oracle函数中硬编码它,它看起来很好,但以某种方式传递它失败了:(这让我发疯。正如我在前面的回答中所说的那样::是的,插入ONETABLE(GUID,START_DATE,END_DATE)值(p_GUID,p_START_DATE,p_END_DATE);也不起作用。这是原始的。我对_date执行此操作的唯一原因是尝试修复它不起作用。好的。正如我在对上一个答案的评论中所说:-)此错误与转换客户端参数有关。当参数传递到Oracle时,不需要进行转换。是的,但是如何解决这个问题呢?c#发送日期类型(确切地说是datetime),oracle需要日期类型。我能做什么我认为这是字符串格式,而不是日期时间。您使用哪个引擎访问数据库?