为什么要获得ORA-01858:找到一个非数字字符,其中数字是预期的?

时间:2016-02-03 08:56:08

标签: oracle plsql

我正在使用xml表。我的日期类型列有问题。有人可以查看我的代码并告诉我我的代码有什么问题,因为我无法弄明白。

我的表TBL_EMP_BASIC_PROFILE是:

Name                  Null     Type          
--------------------- -------- ------------- 
EBASP_ID              NOT NULL VARCHAR2(10)  
EBASP_NAME                     VARCHAR2(50)  
B_EBASP_NAME                   VARCHAR2(150) 
EBASP_GENDER                   VARCHAR2(8)   
EBASP_CATEGORY                 VARCHAR2(10)  
EBASP_REGION_TYPE              VARCHAR2(20)  
EBASP_REGION_NAME              VARCHAR2(50)  
EBASP_SUB_REGION               VARCHAR2(50)  
EBASP_LOCATION                 VARCHAR2(100) 
EBASP_DESIGNATION              VARCHAR2(50)  
B_EBASP_DESIGNATION            VARCHAR2(150) 
EBASP_DATE_OF_JOINING          DATE          
EBASP_GRADE                    NUMBER(2)     
EBASP_BASIC                    NUMBER(7)     
EBASP_PHOTO_UPLOAD             VARCHAR2(500) 
EBASP_CREATED_ON               DATE          
EBASP_CREATED_BY               VARCHAR2(10)  

我的套餐功能是:

FUNCTION save_emp_basic_profile(employeeData VARCHAR2) RETURN CLOB IS

ret CLOB;
xmlData XMLType;
v_code NUMBER;
v_errm VARCHAR2(500);

BEGIN

xmlData:=XMLType(employeeData);
INSERT INTO TBL_EMP_BASIC_PROFILE SELECT temp1.* FROM XMLTABLE('/employees/employee'
                                  PASSING xmlData
                                  COLUMNS ebasp_id VARCHAR2(10) PATH 'ebasp_id',
                                          ebasp_name VARCHAR2(50) PATH 'ebasp_name',
                                          b_ebasp_name VARCHAR2(150) PATH 'b_ebasp_name',
                                          ebasp_gender VARCHAR2(8) PATH 'ebasp_gender',
                                          ebasp_category VARCHAR2(10) PATH 'ebasp_category',
                                          ebasp_region_type VARCHAR2(50) PATH 'ebasp_region_type',
                                          ebasp_region_name VARCHAR2(50) PATH 'ebasp_region_name',
                                          ebasp_sub_region VARCHAR2(50) PATH 'ebasp_sub_region',
                                          ebasp_location VARCHAR2(100) PATH 'ebasp_location',
                                          ebasp_designation VARCHAR2(50) PATH 'ebasp_designation',
                                          b_ebasp_designation VARCHAR2(150) PATH 'b_ebasp_designation',
                                          ebasp_date_of_joining DATE PATH 'ebasp_date_of_joining',
                                          ebasp_grade NUMBER(2) PATH 'ebasp_grade',
                                          ebasp_basic NUMBER(7) PATH 'ebasp_basic',
                                          ebasp_photo_upload VARCHAR2(500) PATH 'ebasp_photo_upload',
                                          ebasp_created_on DATE PATH 'ebasp_created_on',
                                          ebasp_created_by VARCHAR2(50) PATH 'ebasp_created_by')temp1;
ret:=to_char(sql%rowcount);  
COMMIT;

RETURN '<result><status affectedRow='||ret1||'>Success</status></result>';
DBMS_OUTPUT.PUT_LINE(ret);
EXCEPTION
WHEN OTHERS THEN
v_code := SQLCODE;
v_errm := SUBSTR(SQLERRM, 1 , 500);
DBMS_OUTPUT.PUT_LINE('Error code ' || v_code || ': ' || v_errm);
RETURN '<result><status>Error'||v_errm||'</status></result>';
END save_emp_basic_profile;

我的输入pl sql是:

declare
  query_result clob;
begin
  query_result := *package_name*.SAVE_EMP_BASIC_PROFILE
  ('<employees>
    <employee>
        <ebasp_id>1234567890</ebasp_id>
        <ebasp_name></ebasp_name>
        <b_ebasp_name></b_ebasp_name>
        <ebasp_gender></ebasp_gender>
        <ebasp_category></ebasp_category>
        <ebasp_region_type></ebasp_region_type>
        <ebasp_region_name></ebasp_region_name>
        <ebasp_sub_region></ebasp_sub_region>
        <ebasp_location></ebasp_location>
        <ebasp_designation></ebasp_designation>
        <b_ebasp_designation></b_ebasp_designation>
        <ebasp_date_of_joining>to_date(''2-2-2016'',''DD-MM-YYYY'')</ebasp_date_of_joining>
        <ebasp_grade></ebasp_grade>
        <ebasp_basic></ebasp_basic>
        <ebasp_photo_upload></ebasp_photo_upload>
        <ebasp_created_on>to_date(''3-2-2016'',''DD-MM-YYYY'')</ebasp_created_on>
        <ebasp_created_by></ebasp_created_by>
        <econt_cell_number></econt_cell_number>
        <econt_phone_number></econt_phone_number>
        <econt_email></econt_email>
        <econt_village_or_street></econt_village_or_street>
        <b_econt_village_or_street></b_econt_village_or_street>
        <econt_thana></econt_thana>
        <b_econt_thana></b_econt_thana>
        <econt_post_office></econt_post_office>
        <b_econt_post_office></b_econt_post_office>
        <econt_postal_code></econt_postal_code>
        <b_econt_postal_code></b_econt_postal_code>
        <econt_district></econt_district>
    </employee>
</employees>');
end;  

仅提供id和1个日期作为输入(id必须作为主键)。但是我收到了这个错误:Error code -1858: ORA-01858: a non-numeric character was found where a numeric was expected。有人可以告诉我在日期类型列中输入日期的正确方法。因为我尝试过to_date()函数但没有好处。

2 个答案:

答案 0 :(得分:4)

不要将to_date放在你的xml中;这样,你就可以拔出字符串&#34; to_date(&#39;&#39; 2-2-2016&#39;&#39;&#39;&#39;&#39; DD-MM -YYYY&#39;&#39;)&#34;您当时希望转换成日期 - 即。 insert into tbl_emp_basic_profile -- where is the list of columns? You should explicitly list the columns you're inserting into, esp in production code! select ebasp_id, ebasp_name, b_ebasp_name, ebasp_gender, ebasp_category, ebasp_region_type, ebasp_region_name, ebasp_sub_region, ebasp_location, ebasp_designation, b_ebasp_designation, to_date(ebasp_date_of_joining, 'dd-mm-yyyy') ebasp_date_of_joining, ebasp_grade, ebasp_basic, ebasp_photo_upload, to_date(ebasp_created_on, 'dd-mm-yyyy') ebasp_created_on, ebasp_created_by from xmltable('/employees/employee' passing xmldata columns ebasp_id varchar2(10) path 'ebasp_id', ebasp_name varchar2(50) path 'ebasp_name', b_ebasp_name varchar2(150) path 'b_ebasp_name', ebasp_gender varchar2(8) path 'ebasp_gender', ebasp_category varchar2(10) path 'ebasp_category', ebasp_region_type varchar2(50) path 'ebasp_region_type', ebasp_region_name varchar2(50) path 'ebasp_region_name', ebasp_sub_region varchar2(50) path 'ebasp_sub_region', ebasp_location varchar2(100) path 'ebasp_location', ebasp_designation varchar2(50) path 'ebasp_designation', b_ebasp_designation varchar2(150) path 'b_ebasp_designation', ebasp_date_of_joining varchar2(10) path 'ebasp_date_of_joining', ebasp_grade number(2) path 'ebasp_grade', ebasp_basic number(7) path 'ebasp_basic', ebasp_photo_upload varchar2(500) path 'ebasp_photo_upload', ebasp_created_on varchar2(10) path 'ebasp_created_on', ebasp_created_by varchar2(50) path 'ebasp_created_by') temp1; 我认为你可以看到它是一个非首发。

相反,将日期保留为字符串,例如:... listener = new TcpListener(System.Net.IPAddress.Any, 4711); listener.Start(); while(true){ TcpClient c = listener.AcceptTcpClient(); } ... ,将xmltable中列的数据类型更改为varchar2,然后将转换作为插入的一部分进行转换,如下所示:

...
TcpClient c = new TcpClient("myip", 4711);
StreamReader inStream = new StreamReader(c.GetStream());
...

更好的做法是将每个日期使用的日期掩码作为XML中每个日期节点的属性,这样您就不必事先知道日期字符串的格式;这样,如果生成的xml想要改变它们格式化日期的方式,它应该对数据库不可见。我知道可能无法让XML生成器添加它。

答案 1 :(得分:0)

在您的代码中使用to_char而不是to_date('2-2-2016','DD-MM-YYYY')。也许这就是错误的来源?