换行符\ n给出“java.sql.SQLException:ORA-00911:无效字符\ n”Oracle 11g

问题描述:

我有Oracle DB 11g企业版,我想通过从文件中读取sql脚本来创建表。 Java代码我读下面从文件sql脚本并将其存储在一个String sqlBlock换行符 n给出“java.sql.SQLException:ORA-00911:无效字符 n”Oracle 11g

CREATE SEQUENCE VerHist_SeqNum 
    START WITH 1 
    INCREMENT BY 1; 
CREATE TABLE VerHist 
(
    SequenceNumber NUMBER(10,0) NOT NULL, 
    SQLFileName VARCHAR2(100) NOT NULL, 
    STATUS VARCHAR2(10) NOT NULL, 
    AppliedDate DATE NOT NULL, 
    DateCreated DATE 
    DEFAULT (SYSDATE), 
    DateUpdated DATE 
    DEFAULT (SYSDATE), 
    CONSTRAINT PK_VerHist PRIMARY KEY(SequenceNumber), 
    CONSTRAINT UC_VerHist_SQLFileNa UNIQUE(SQLFileName) 
); 
CREATE OR REPLACE TRIGGER VerHist_SeqNum_TRG 
    BEFORE INSERT 
    ON VerHist 
    FOR EACH ROW 
    BEGIN 
     SELECT VerHist_SeqNum.NEXTVAL INTO :NEW.SequenceNumber 
     FROM DUAL; 
    END; 

当我执行此查询它给

值java.sql.SQLException:ORA-00911:无效字符\ n 在(oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java))。 :288)at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:743)at oracle.jdbc.driver.T4CStatement.doOall8(T4CStatement.java:207)at oracle.jdbc.driver.T4CStatement.executeForRows (T4CStatement.java:946) 在 oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1168) 在 oracle.jdbc.driver.OracleStatement.executeInternal(OracleStatement.java:1687) 在 预言。 jdbc.driver.OracleStatement.execute(OracleStateme nt.java:1653)

以下是我的代码执行的SQL块:

Statement stmt = conn.createStatement(); 
String sqlBlock = //"this contains the content of the file (it contains \n charters)"; 
stmt.execute(sqlBlock); 

是换行章程无效这里,如果是,如何得到这个工作,不然?

请注意,当我复制粘贴此文件的内容并通过Oracle SQL Developer运行脚本它运行良好。

+1

为什么你有\ n字符?删除它们... –

+0

尝试使用转义字符意味着\\ n代替\ n –

+0

我尝试用单个空格替换'\ n',也试过'\\ n'而不是'\ n',但仍然得到相同的错误信息。 – Learner

我认为\n引用是一个红鲱鱼,并且是如何记录错误的人造物。您正试图在一个execute中运行两个用分号分隔的SQL语句。这是不允许的。分号是SQL * Plus中的语句分隔符,不在SQL中,即使使用单个语句也会生成ORA-00911。并execute必须是一个单一的声明。

如果你在做DML,你可以把这些语句包装在PL/SQL块中并执行它,但是因为这是DDL,所以你不能这么做,除非你使用动态SQL,这会变得过于复杂,对于你想要做的事情而言,这是凌乱的。

您需要将每个语句放在单独的文件中(create sequence上没有尾随分号;因为它在结束触发器的PL/SQL块时仍需要它,因此它不会作为语句分隔符 - 我感到困惑,我知道),并分别阅读和执行它们。然后每个execute有一个单一的声明,并会更快乐。


另外,你不需要在11g中选择你的序列值到你的变量中; you can now do it like this

CREATE OR REPLACE TRIGGER VerHist_SeqNum_TRG 
BEFORE INSERT 
ON VerHist 
FOR EACH ROW 
BEGIN 
    :NEW.SequenceNumber := VerHist_SeqNum.NEXTVAL; 
END; 
+0

嗨,亚历克斯,是的,这可能是问题,将尝试这一点。谢谢 – Learner

+0

感谢亚历克斯,你的解决方案工作+1。请原谅我在Oracle和SQL方面的知识缺乏,请告诉我如何根据您对11g中变量的最新建议改变我的sql语句。 – Learner

+0

这里是分号:NEW.SequenceNumber:= VerHist_SeqNum.NEXTVAL;'optional?我可以删除它吗?问这个是因为我改变了我的java代码,认为SQL语句以分号结尾。 – Learner

当您复制粘贴文件的包含到浏览器。浏览器会将\ n视为新行。 鉴于代码/ n只是字符。 尝试更换\ n,其中单个空格,然后运行它会工作

+0

我试着用单个空格替换'\ n',但仍然得到相同的错误消息。 – Learner

+0

@John请问你可以添加解释你如何阅读文件的代码 – Sach

sqlBlock = sqlBlock.replaceAll("\n"," ");

从查询中删除\ n。如果你想在sql开发者中查询格式,你可以选择查询并按Ctrl + F7

+0

我试过了,它不起作用,我仍然得到相同的错误。 – Learner

+0

你可以粘贴整个语句而不是 'String sqlBlock = //“这包含文件的内容(它包含\ n章程)”;' – atripathi