GVKun编程网logo

Java中的参数化Oracle SQL查询?(java 参数化类型)

16

针对Java中的参数化OracleSQL查询?和java参数化类型这两个问题,本篇文章进行了详细的解答,同时本文还将给你拓展ArcGISJavaScriptAPI中的参数化查询、asp.net–Ora

针对Java中的参数化Oracle SQL查询?java 参数化类型这两个问题,本篇文章进行了详细的解答,同时本文还将给你拓展ArcGIS JavaScript API 中的参数化查询、asp.net – Oracle中的参数化查询问题、c# – 如何编写参数化的oracle插入查询?、java – 在Oracle数据库中调用查询时更改绑定后的参数值等相关知识,希望可以帮助到你。

本文目录一览:

Java中的参数化Oracle SQL查询?(java 参数化类型)

Java中的参数化Oracle SQL查询?(java 参数化类型)

我一直在试图弄清楚为什么以下代码未在我的ResultSet中生成任何数据:

String sql = "SELECT STUDENT FROM SCHOOL WHERE SCHOOL = ? ";PreparedStatement prepStmt = conn.prepareStatement(sql);prepStmt.setString(1, "Waterloo");ResultSet rs = prepStmt.executeQuery();

另一方面,以下各项可以正常运行:

String sql = "SELECT STUDENT FROM SCHOOL WHERE SCHOOL = ''Waterloo'' ";PreparedStatement prepStmt = conn.prepareStatement(sql);ResultSet rs = prepStmt.executeQuery();

SCHOOL的数据类型为CHAR(9字节)。除了setString,我还尝试了:

String sql = "SELECT STUDENT FROM SCHOOL WHERE SCHOOL = ? ";PreparedStatement prepStmt = conn.prepareStatement(sql);String school = "Waterloo";Reader reader = new CharArrayReader(school.toCharArray());prepStmt.setCharacterStream(1, reader, 9);prepStmt.setString(1, "Waterloo");ResultSet rs = prepStmt.executeQuery();

我完全留意接下来要研究什么;Eclipse调试器说,即使在setString或setCharacterStream之后,SQL查询也不会更改。我不确定这是因为设置参数不起作用,还是调试器根本无法在PreparedStatement中获取更改。

任何帮助将不胜感激,谢谢!

答案1

小编典典

我认为问题在于您的数据类型为CHAR(9),而“滑铁卢”只有8个字符。我认为这将返回预期的结果(LIKE和%)。或添加缺少的空间。

String sql = "SELECT STUDENT FROM SCHOOL WHERE SCHOOL LIKE ? ";PreparedStatement prepStmt = conn.prepareStatement(sql);prepStmt.setString(1, "Waterloo%");ResultSet rs = prepStmt.executeQuery();

如果您的字符串长度灵活,最好的方法是使用varchar而不是char。然后,PreparedStatement将按预期工作。

一种解决方法是使用Oracle特定的setFixedCHAR方法(但如果可能,最好将数据类型更改为varchar)。

以下来自Oracle的PreparedStatement JavaDoc:


数据库中的CHAR数据将填充为列宽。这导致在使用setCHAR()方法将字符数据绑定到SELECT语句的WHERE子句中受到限制-
WHERE子句中的字符数据还必须填充到列宽以在SELECT语句中产生匹配项。如果您不知道列宽,则尤其麻烦。

setFixedCHAR()对此进行了补救。此方法执行非填充比较。

笔记:

  • 请记住将您准备好的语句对象转换为OraclePreparedStatement以使用setFixedCHAR()方法。
  • 对于INSERT语句,无需使用setFixedCHAR()。数据库在插入数据时始终自动将其填充到列宽。

下面的示例演示setString(),setCHAR()和setFixedCHAR()方法之间的区别。

// Schema is : create table my_table (col1 char(10));//             insert into my_table values (''JDBC'');PreparedStatement pstmt = conn.prepareStatement("select count() from my_table where col1 = ?");ResultSet rs;pstmt.setString (1, "JDBC");  // Set the Bind Valuers = pstmt.executeQuery();    // This does not match any row// ... do something with rsCHAR ch = new CHAR("JDBC      ", null);((OraclePreparedStatement)pstmt).setCHAR(1, ch); // Pad it to 10 bytesrs = pstmt.executeQuery();     // This matches one row// ... do something with rs((OraclePreparedStatement)pstmt).setFixedCHAR(1, "JDBC");rs = pstmt.executeQuery();     // This matches one row// ... do something with rs

ArcGIS JavaScript API 中的参数化查询

ArcGIS JavaScript API 中的参数化查询

如何解决ArcGIS JavaScript API 中的参数化查询?

我正在尝试在 ArcGIS JavaScript API 中为 ArcGIS 图层查询构建 where 子句。我能找到的所有示例(包括在 where documentation 中)都鼓励您这样做:

query.where = "NAME = ''" + stateName + "''";

我觉得这令人惊讶,因为我们似乎被鼓励编写易受 SQL injection bugs 影响的代码。这对我来说尤其重要,因为我的“stateName”完全不在我的控制范围内。这是原始用户输入。

看起来该库支持通过 parameterValues 属性进行查询参数化,但是我找不到有关如何使用它的示例,或者如何格式化我的查询以使其使用参数值。甚至文档也不包含任何示例。

那么我们如何创建正确参数化的查询?

旁注:我知道服务器管理员的工作可能是防止错误的查询造成损害,但是我问这个问题的一半原因也纯粹是为了避免错误和不正确解析的查询。

解决方法

According to ESRI,parameterValues 属性仅用于使用查询层。它不适用于此上下文。

所以答案是,不,当您只是在图层上运行查询时,您不能使用正确的 SQL 参数化。

我发现让您的查询至少更防弹的最好方法是使用这样的代码:

function sanitizeParameter(value) {
    // We need to escape single quotes to avoid messing up SQL syntax.
    // So all '' characters need to become ''''
    return value.split("''").join("''''")
}

query.where = "NAME = ''" + sanitizeParameter(stateName) + "''";

asp.net – Oracle中的参数化查询问题

asp.net – Oracle中的参数化查询问题

我正在使用Oracle.DataAccess而不是过时的System.Data.OracleClient,我似乎无法将多个参数传递到我的更新查询

这个工作

OracleCommand.CommandText = "UPDATE db SET column1 = :param1 WHERE column2 = 'Y'"
OracleCommand.Parameters.Add(New OracleParameter("param1","1234"))

但是我想要能够传递多个参数

这是我的完整代码

OracleConn.open()
    OracleCommand = OracleConn.CreateCommand()
    OracleCommand.CommandText = "UPDATE db SET column1 = :param1 WHERE column2 = :param2"
    OracleCommand.CommandType = CommandType.Text
    OracleCommand.Parameters.Add(New OracleParameter("param1","1234"))
    OracleCommand.Parameters.Add(New OracleParameter("param2","Y"))
    OracleCommand.ExecuteNonQuery()

传递多个参数但不是更新时,我的SELECT查询似乎工作

解决方法

虽然我看不到你的例子有什么问题,我想知道你是否被老BindByName问题打了。默认情况下,ODP.NET按照要添加到集合中的顺序将参数绑定到查询中,而不是根据您的名称。尝试在您的OracleCommand对象上将BindByName设置为true,看看是否可以解决问题。

我已经遇到这个问题了很多次,我使用我自己的工厂方法来创建自动将此属性设置为true的命令。

经典无用的Oracle文档here

c# – 如何编写参数化的oracle插入查询?

c# – 如何编写参数化的oracle插入查询?

我使用oracle作为我的后端,我写如下插入查询,我不知道是不是正确的方式,

insert into Emp_table (SL_NO,empane,empid,salaray) values(1,'sree',1002,:salary);

在这里查询我正在用存储过程计算工资并得到我的out参数工资所以我必须将它传递给我的插入查询所以我怎么能写.如果我像所示那样写,我会得到低于错误

ORA-06550: line 1,column 175:
PL/sql: ORA-00933: sql command not properly ended
ORA-06550: line 1,column 7:
PL/sql: sql Statement ignored

请帮助我.

解决方法

假设工资金额为20000,您可以尝试以下代码:

var commandText = "insert into Emp_table (SL_NO,salaray) values(:SL_NO,:empane,:empid,:salary)";

using (OracleConnection connection = new OracleConnection(connectionString))
using (OracleCommand command = new OracleCommand(commandText,connection))
{
    command.Parameters.AddWithValue("SL_NO",1);
    command.Parameters.AddWithValue("empane","sree");
    command.Parameters.AddWithValue("empid",1002);
    command.Parameters.AddWithValue("salaray",20000);
    command.Connection.open();
    command.ExecuteNonQuery();
    command.Connection.Close();
}

java – 在Oracle数据库中调用查询时更改绑定后的参数值

java – 在Oracle数据库中调用查询时更改绑定后的参数值

我们在公司里有使用 Java 7,Spring Framework 3.1.2,MyBatis 3.1.1,MyBatis Spring 1.2.2,JasperReports 6.1.0等开发的应用程序.应用程序在Tomcat 7.0.35上运行,使用Tomcat连接池与Oracle数据库10g企业版10.2.0.4.0版的连接 – 64位. JRE版本1.7.0_09-b05.应用程序适用于RHEL Server 6.5.

有时出现问题,然后在几小时(3-6小时)后消失,有时几天(1-3天)消失.当创建一个报告Web服务,应用程序调用从MyBatis的映射器,它返回列表与LT方法; MonthlyReport&gt ;,然后应用程序传递这个列表来JasperReport的发动机的文件系统上创建的报告,并且在响应文件的结尾,应用程序返回流(MTOM ).问题是,当尝试在数据库中运行查询以创建报告时,会定期导致以下异常:

ERROR 2015-07-23 11:44:03,012 [http-bio-8280-exec-2] exception type: org.springframework.jdbc.UncategorizedsqlException
ERROR 2015-07-23 11:44:03,012 [http-bio-8280-exec-2] exception message: 
### Error querying database.  Cause: java.sql.sqlException: ORA-12801: error signaled in parallel query server P010
ORA-01841: (full) year must be between -4713 and +9999,and not be 0

这是查询:

<select id="getMonthlyReportData" resultType="MonthlyReport" parameterType="map">
<![CDATA[
SELECT r.bank_name bankName,r.user_name userName,r.descr userDescription,CASE WHEN r.parent_bank_id IS NULL THEN 1 ELSE 0 END isParentBankInt,COUNT (CASE WHEN r.p_type NOT IN ('SS','DR') THEN 1 ELSE NULL END) postpaidPaymentCount,SUM (CASE WHEN r.p_type NOT IN ('SS','DR') THEN r.amount ELSE 0 END) postpaidPaymentAmount,COUNT (CASE WHEN r.p_type = 'SS' THEN 1 ELSE NULL END) prepaidPaymentCount,SUM (CASE WHEN r.p_type = 'SS' THEN r.amount ELSE 0 END) prepaidPaymentAmount,COUNT (CASE WHEN r.p_type = 'DR' THEN 1 ELSE NULL END) depositRepayCount,SUM (CASE WHEN r.p_type = 'DR' THEN r.amount ELSE 0 END) depositRepayAmount
  FROM (SELECT q.queue_id,q.amount,q.p_type,q.user_name,q.action_date,b.parent_bank_id,U.descr,b.bank_name
          FROM rbp_queue q,rbp_all_banks b,rbp_users U
         WHERE     q.user_name = U.user_name
               AND U.working_bank_id = b.bank_id
               AND q.err_code = -1000000
               AND q.action_date BETWEEN TO_DATE (#{start_date,javaType=STRING,jdbcType=VARCHAR},'YYYYMMDDHH24MISS')
                                     AND TO_DATE (#{end_date,'YYYYMMDDHH24MISS')
               AND U.working_bank_id IN
                    (SELECT bank_id
                       FROM rbp_all_banks
                      WHERE bank_id = #{bank_id,javaType=Integer,jdbcType=NUMERIC} OR parent_bank_id = #{bank_id,jdbcType=NUMERIC})
        UNION
        SELECT qa.queue_id,qa.amount,qa.p_type,qa.user_name,qa.action_date,ba.parent_bank_id,Ua.descr,ba.bank_name
          FROM sysadm.rbp_queue_arch@azis_archdb qa,rbp_all_banks ba,rbp_users Ua
         WHERE     qa.user_name = Ua.user_name
               AND Ua.working_bank_id = ba.bank_id
               AND qa.err_code = -1000000
               AND qa.action_date BETWEEN TO_DATE (#{start_date,'YYYYMMDDHH24MISS')
                                      AND TO_DATE (#{end_date,'YYYYMMDDHH24MISS')
               AND Ua.working_bank_id IN
                    (SELECT bank_id
                       FROM rbp_all_banks
                      WHERE bank_id = #{bank_id,jdbcType=NUMERIC})) r
         GROUP BY r.bank_name,r.user_name,r.descr,CASE WHEN r.parent_bank_id IS NULL THEN 1 ELSE 0 END
         ORDER BY isParentBankInt DESC,bankName,userName
]]>

应用程序不使用日期类型参数,因为在这种情况下Oracle使用不同的计划,并且查询运行很长时间.因此,应用程序将查询日期作为文本传递给查询日期,然后使用TO_DATE函数将其转换为日期.
来自MyBatis的日志记录:

DEBUG 2015-07-22 15:10:52,720 [http-apr-8281-exec-2] ooo Using Connection [ProxyConnection[PooledConnection[oracle.jdbc.driver.T4CConnection@344482ac]]]
DEBUG 2015-07-22 15:10:52,724 [http-apr-8281-exec-2] ==>  Preparing: SELECT r.bank_name bankName,...
DEBUG 2015-07-22 15:10:52,725 [http-apr-8281-exec-2] ==> Parameters: 20150601000000(String),20150621235959(String),31(Integer),20150601000000(String),31(Integer)

如此处所示,MyBatis将日期参数(作为字符串)传递给查询,但是如果要查看Oracle跟踪,我们可以看到,日期参数的值是“”(不是空,而是两个双引号).

呼唤

SELECT TO_DATE ('','YYYYMMDDHH24MISS') FROM dual

at TOAD返回null值,但是

SELECT TO_DATE ('""','YYYYMMDDHH24MISS') FROM dual

引发异常:ORA-01841 :(完整)年份必须介于-4713和9999之间,而不是0.

奇怪的是,当服务器出现问题时,同时应用程序在其他计算机(例如我的工作笔记本电脑)上运行时没有问题(创建此报告).
发生问题时,下面是Oracle数据库的跟踪文件的一部分:

Bind#0
      oacdty=01 mxl=32(28) mxlc=00 mal=00 scl=00 pre=00
      oacflg=03 fl2=1000010 frm=02 csi=2000 siz=224 off=0
      kxsbbbfp=9fffffffbf330908  bln=32  avl=28  flg=05
      value=""
     Bind#1
      oacdty=01 mxl=32(28) mxlc=00 mal=00 scl=00 pre=00
      oacflg=03 fl2=1000010 frm=02 csi=2000 siz=0 off=32
      kxsbbbfp=9fffffffbf330928  bln=32  avl=28  flg=01
      value=""
     Bind#2
      oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
      oacflg=03 fl2=1000000 frm=02 csi=2000 siz=0 off=64
      kxsbbbfp=9fffffffbf330948  bln=22  avl=02  flg=01
      value=31
     Bind#3
      oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
      oacflg=03 fl2=1000000 frm=02 csi=2000 siz=0 off=88
      kxsbbbfp=9fffffffbf330960  bln=22  avl=02  flg=01
      value=31
     Bind#4
      oacdty=01 mxl=32(28) mxlc=00 mal=00 scl=00 pre=00
      oacflg=03 fl2=1000010 frm=02 csi=2000 siz=0 off=112
      kxsbbbfp=9fffffffbf330978  bln=32  avl=28  flg=01
      value=""
     Bind#5
      oacdty=01 mxl=32(28) mxlc=00 mal=00 scl=00 pre=00
      oacflg=03 fl2=1000010 frm=02 csi=2000 siz=0 off=144
      kxsbbbfp=9fffffffbf330998  bln=32  avl=28  flg=01
      value=""
     Bind#6
      oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
      oacflg=03 fl2=1000000 frm=02 csi=2000 siz=0 off=176
      kxsbbbfp=9fffffffbf3309b8  bln=22  avl=02  flg=01
      value=31
     Bind#7
      oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
      oacflg=03 fl2=1000000 frm=02 csi=2000 siz=0 off=200
      kxsbbbfp=9fffffffbf3309d0  bln=22  avl=02  flg=01
      value=31

以下是未出现问题时Oracle数据库的跟踪文件的一部分:

Bind#0
      oacdty=01 mxl=32(14) mxlc=00 mal=00 scl=00 pre=00
      oacflg=03 fl2=1000010 frm=01 csi=31 siz=224 off=0
      kxsbbbfp=9fffffffbf323e50  bln=32  avl=14  flg=05
      value="20150601000000"
     Bind#1
      oacdty=01 mxl=32(14) mxlc=00 mal=00 scl=00 pre=00
      oacflg=03 fl2=1000010 frm=01 csi=31 siz=0 off=32
      kxsbbbfp=9fffffffbf323e70  bln=32  avl=14  flg=01
      value="20150621235959"
     Bind#2
      oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
      oacflg=03 fl2=1000000 frm=01 csi=31 siz=0 off=64
      kxsbbbfp=9fffffffbf323e90  bln=22  avl=02  flg=01
      value=31
     Bind#3
      oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
      oacflg=03 fl2=1000000 frm=01 csi=31 siz=0 off=88
      kxsbbbfp=9fffffffbf323ea8  bln=22  avl=02  flg=01
      value=31
     Bind#4
      oacdty=01 mxl=32(14) mxlc=00 mal=00 scl=00 pre=00
      oacflg=03 fl2=1000010 frm=01 csi=31 siz=0 off=112
      kxsbbbfp=9fffffffbf323ec0  bln=32  avl=14  flg=01
      value="20150601000000"
     Bind#5
      oacdty=01 mxl=32(14) mxlc=00 mal=00 scl=00 pre=00
      oacflg=03 fl2=1000010 frm=01 csi=31 siz=0 off=144
      kxsbbbfp=9fffffffbf323ee0  bln=32  avl=14  flg=01
      value="20150621235959"
     Bind#6
      oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
      oacflg=03 fl2=1000000 frm=01 csi=31 siz=0 off=176
      kxsbbbfp=9fffffffbf323f00  bln=22  avl=02  flg=01
      value=31
     Bind#7
      oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
      oacflg=03 fl2=1000000 frm=01 csi=31 siz=0 off=200
      kxsbbbfp=9fffffffbf323f18  bln=22  avl=02  flg=01
      value=31

注意绑定的值:0,1,4,5.出现问题时,值为value =“”.

该问题与MyBatis无关,因为在请求进入已编译的JasperReports文件(monthlyReport.jasper)之前,应用程序将数据库连接传递给JasperReports引擎以创建报告. JasperReports本身连接到数据库并运行查询. MyBatis不用于创建报告,但在应用程序中用于所有其他目的.同样的Oracle错误(ORA-01841 :(完整)年份必须在-4713和9999之间,而不是0)定期发布和那里.从旧日志文件:

ERROR 2015-06-11 08:57:17,559 [http-apr-8280-exec-9] Fill 1: exception
    net.sf.jasperreports.engine.JRException: Error executing sql statement for : monthlyReport_New32Dataset321_1432644594876_272524
            at net.sf.jasperreports.engine.query.JRJdbcQueryExecuter.createDatasource(JRJdbcQueryExecuter.java:240)
            at net.sf.jasperreports.engine.fill.JRFillDataset.createqueryDatasource(JRFillDataset.java:1087)
            at net.sf.jasperreports.engine.fill.JRFillDataset.initDatasource(JRFillDataset.java:668)
            at net.sf.jasperreports.engine.fill.JRBaseFiller.setParameters(JRBaseFiller.java:1281)
            at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:900)
            at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:845)
            at net.sf.jasperreports.engine.fill.JRFillSubreport.fillSubreport(JRFillSubreport.java:651)
            at net.sf.jasperreports.engine.fill.JRSubreportRunnable.run(JRSubreportRunnable.java:59)
            at net.sf.jasperreports.engine.fill.AbstractThreadSubreportRunner.run(AbstractThreadSubreportRunner.java:203)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
            at java.lang.Thread.run(Thread.java:722)
    Caused by: java.sql.sqlException: ORA-12801: error signaled in parallel query server P002
    ORA-01841: (full) year must be between -4713 and +9999,and not be 0

            at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:445)
            at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:396)
            at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:879)
            at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:450)
            at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:192)
            at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:531)
            at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:207)
            at oracle.jdbc.driver.T4CPreparedStatement.executeForDescribe(T4CPreparedStatement.java:884)
            at oracle.jdbc.driver.OracleStatement.executeMaybedescribe(OracleStatement.java:1167)
            at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1289)
            at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3584)
            at oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:3628)
            at oracle.jdbc.driver.OraclePreparedStatementWrapper.executeQuery(OraclePreparedStatementWrapper.java:1493)
            at sun.reflect.GeneratedMethodAccessor349.invoke(UnkNown Source)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
            at java.lang.reflect.Method.invoke(Method.java:601)
            at org.apache.tomcat.jdbc.pool.interceptor.AbstractQueryReport$StatementProxy.invoke(AbstractQueryReport.java:235)
            at $Proxy99.executeQuery(UnkNown Source)
            at net.sf.jasperreports.engine.query.JRJdbcQueryExecuter.createDatasource(JRJdbcQueryExecuter.java:233)
            ... 11 more

请帮忙解决这个问题.

解决方法

您正在观察症状.这不是引号的问题.在跟踪中,字符串参数显示为doulbe引号.即

value="20150621235959"

表示客户端传递了字符串’20150621235959’和

value=""

表示客户端传递了一个空字符串”.领导ORA-12801

根本原因是客户端能够将空字符串传递给数据库.

谓词

action_date BETWEEN date1 and date2

如果一个或两个日期为NULL,则不返回任何行.如果你不信任简单运行这个查询

-- return nothing
 SELECT * FROM dual where sysdate between to_date('','ddmmyyyy') and to_date('','ddmmyyyy');

没有必要为什么客户端应该向数据库发送空字符串,如果你知道,什么都不会返回.

所以IMHO应该在客户端执行一些验证,只接受有效的字符串(至少是正确的长度).这将解决问题.

我们今天的关于Java中的参数化Oracle SQL查询?java 参数化类型的分享已经告一段落,感谢您的关注,如果您想了解更多关于ArcGIS JavaScript API 中的参数化查询、asp.net – Oracle中的参数化查询问题、c# – 如何编写参数化的oracle插入查询?、java – 在Oracle数据库中调用查询时更改绑定后的参数值的相关信息,请在本站查询。

本文标签: