我在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_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(上面的示例)来尝试解决问题):
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, p_START_DATE, p_END_DATE);
COMMIT;
EXCEPTION
WHEN OTHERS THEN
p_RETURN:= 1;
END;
从c#调用它时(例如,使用DateTime.NOW) - 它失败。
如果开始日期和结束日期的格式为05-apr-2013,则似乎只能起作用。但是我如何在那里和输入中获得时间?
如果我更换
p_START_DATE, 'YYYY-MM-DD HH24:MI:SS'
使用
'2013-05-13 12:13:14', 'YYYY-MM-DD HH24:MI:SS'
这样可行,但是从c#调用过程后它就失败了。
此外,如果我从数据库客户端手动运行该过程,我仍然需要输入05-apr-2013并且只能这样做。如果我尝试的话,我无法输入时间。
开始日期和结束日期是oracle db中的DATE类型。
-
根据我的尝试,我得到不同的消息。
正如我调查的那样,它似乎与此有关:
SELECT value FROM v$nls_parameters WHERE parameter ='NLS_DATE_FORMAT';
返回:
DD-MON-RR
我不能改变它,因为我不是数据库所有者。
-
那么如何让时间在那里?
这是完整的SQL:
select parameter, value from nls_session_parameters;
返回:
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
答案 0 :(得分:2)
由于您的列在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(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
vs你是隐含的转换:
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
答案 1 :(得分:1)
无需将功能转换为DATE
类型。它已经约会了。
只需插入参数:
INSERT INTO ONETABLE (GUID, START_DATE, END_DATE)
VALUES (p_GUID, p_START_DATE, p_END_DATE);
<强>更新强>
但是如果上面的变体不起作用并且您看到引发错误,则必须在客户端检查存储过程参数定义。你能验证客户端的p_START_DATE
参数是否具有DateTime类型?
更新2
客户端有错误。 尝试初始化日期参数,如下例所示:
OracleParameter p1 = new OracleParameter();
p1.DbType = DbType.DateTime;
p1.Value = System.DateTime.Now;
错误原因可能是C#组件将参数视为字符串并将其转换为具有默认OS格式的字符串,然后将其传递给Oracle并进行查询。 Oracle尝试将该字符串解析为ONE
存储过程定义中指定的日期类型,并因此而失败,因为需要来自NLS_DATE_FORMAT参数的默认格式。
更新3
错误的真正原因由@ b0x0rz在注释中解释(错误的返回类型)。无论如何,这是客户端的错误...