【问题标题】:How to loop over array and insert records in Oracle database?如何在 Oracle 数据库中循环遍历数组并插入记录?
【发布时间】:2018-11-19 16:25:07
【问题描述】:

我的表单可以选择添加额外字段。用户可以根据需要添加任意数量的字段。一旦他们提交表单,我需要遍历from 范围并在 ORACLE 数据库中插入记录。这是我的代码示例:

<cfquery name="insertRec" datasource="dbs">
    INSERT INTO myTbl(
        RecordID, First, Last, Email, Subject, Description, ActionDt
    ) VALUES
    <cfset count = 1>
    <cfloop from="1" to="#arrayLen(arrData)#" index="i">
    (
        SYS_GUID(),
        <cfqueryparam cfsqltype="cf_sql_varchar" value="#trim(form.first)#" maxlength="50">,
        <cfqueryparam cfsqltype="cf_sql_varchar" value="#trim(form.last)#" maxlength="50">,
        <cfqueryparam cfsqltype="cf_sql_varchar" value="#trim(form.email)#" maxlength="320">,
        <cfqueryparam cfsqltype="cf_sql_varchar" value="#trim(form.column1)#" maxlength="100">, 
        <cfqueryparam cfsqltype="cf_sql_varchar" value="#trim(form.datadescr1)#" maxlength="4000">, 
        CURRENT_TIMESTAMP
    )
    <cfif count NEQ arrayLen(arrDpr)>,</cfif>
    <cfset count++>
</cfloop>

当我尝试测试上面的代码时,第一个问题是我的 Oracle Insert 语句。我收到错误消息:

[Macromedia][Oracle JDBC Driver][Oracle]ORA-00933: SQL command not properly ended

我查看了错误消息,Oracle 插入代码如下所示:

INSERT INTO myTbl(
    RecordID, First, Last, Email, Subject, Description, ActionDt
) VALUES ( 
    SYS_GUID(), 
    (param 1) , 
    (param 2) , 
    (param 3) , 
    (param 4) , 
    (param 5) , 
    CURRENT_TIMESTAMP 
) , 
( 
    SYS_GUID(), 
    (param 1) , 
    (param 2) , 
    (param 3) , 
    (param 4) , 
    (param 5) , 
    CURRENT_TIMESTAMP
) , 
( 
    SYS_GUID(), 
    (param 1) , 
    (param 2) , 
    (param 3) , 
    (param 4) , 
    (param 5) , 
    CURRENT_TIMESTAMP
)

上面的代码显然是错误的,SQL 插入字符串的构建方式不正确。我想知道如何解决这个问题?在 ColdFusion for ORACLE 数据库中执行此操作的最佳方法是什么?

我遇到的另一个问题与 ColdFusion 和在cfqueryparam 中输出数组索引有关。如您所见,主题和描述列的上述值是硬编码的。我正在尝试找到输出数组索引值的方法。例如,如果我的数组有这个值[1,3,2],那么在 cfloop 中我需要在 cfqueryparam 中得到这个:

<cfqueryparam cfsqltype="cf_sql_varchar" value="#trim(form.column#i#)#" maxlength="50"> 
<cfqueryparam cfsqltype="cf_sql_varchar" value="#trim(form.datadescr#i#)#" maxlength="500">

上面的代码是错误的,我不能在另一个## 中包含##。有没有办法获得附加到columndatadescri 的实际值?它们看起来像:

column1   datadescr1
column3   datadescr3
column2   datadescr2

我是甲骨文世界的新手,这是我无法弄清楚的事情。任何帮助将不胜感激。

【问题讨论】:

  • “添加额外字段”是指FirstLastEmailSubjectDescription 可以多次添加,或者它们可以添加EmailDescription,但把其他人排除在外?
  • 其实看你问题的第二部分,我认为你的意思是后者。那么对于插入多行的人来说,这将是一条记录吗?您能否提供一个小例子来说明您的输入以及您希望插入数据库的值?伪代码会很有帮助。
  • @Shawn 你猜对了,我正在保存用户多次输入名字、姓氏和电子邮件。相反,我给了他们一个选项来单击按钮并在必要时添加主题和描述字段。因此,当我遍历表单字段时,我首先复制粘贴,最后复制粘贴,然后有 column1、column2、column3 和 description1、description2 和 description3。这有意义吗?
  • 你用的是什么版本的CF?我忘了。
  • CF10,我们可能很快会迁移到 2016 年或 2018 年。

标签: oracle oracle11g coldfusion insert cfloop


【解决方案1】:

为了在 cfqueryparam 中输出正确的值,你可以使用这个:

<cfqueryparam cfsqltype="cf_sql_varchar" value="#trim(Evaluate('form.column#i#')#" maxlength="50">

或者

<cfset tempCol = FORM["column#i#"]>

然后在您的查询中使用此变量。 另外关于您的查询: 您需要将 Insert Into 设置在循环内或从 dual 使用。这个问题应该有帮助 Best way to do multi-row insert in Oracle?

    INSERT INTO myTbl(
    RecordID, First, Last, Email, Subject, Description, ActionDt
)
    <cfset count = 1>
        <cfloop from="1" to="#arrayLen(arrData)#" index="i">
        (
           select SYS_GUID(),
            <cfqueryparam cfsqltype="cf_sql_varchar" value="#trim(form.first)#" maxlength="50">,
            <cfqueryparam cfsqltype="cf_sql_varchar" value="#trim(form.last)#" maxlength="50">,
            <cfqueryparam cfsqltype="cf_sql_varchar" value="#trim(form.email)#" maxlength="320">,
            <cfqueryparam cfsqltype="cf_sql_varchar" value="#trim(form.column1)#" maxlength="100">, 
            <cfqueryparam cfsqltype="cf_sql_varchar" value="#trim(form.datadescr1)#" maxlength="4000">, 
            CURRENT_TIMESTAMP
        ) from dual
        <cfif count NEQ arrayLen(arrDpr)> union all </cfif>
        <cfset count++>
    </cfloop>

【讨论】:

  • 我仍然收到您在上面提供的代码的错误。似乎evaluate() 没有解决问题。
  • 它应该可以工作,我有一个代码在 prod 中工作,并在动态字段上进行评估。您看到的错误是什么?
  • 啊,等等。修改答案。
  • 不需要 Evaluate()。只需使用 assoc。数组表示法。出于安全原因,最好尽可能避免评估。
  • 是的,但它也很容易被利用。由于在这种情况下有更安全的替代方案,因此根本不需要使用或推荐 evaluate() ;-) @espresso_coffee - FORM 范围是一个结构。要动态访问密钥,请使用 form["staticName"&amp; index] 或您的 cfqueryparam &lt;cfqueryparam value="#trim(form['first'&amp; i])#" ...&gt;
猜你喜欢
  • 1970-01-01
  • 2015-12-23
  • 1970-01-01
  • 2022-11-29
  • 1970-01-01
  • 2013-04-19
  • 2013-08-15
  • 2015-11-14
  • 1970-01-01
相关资源
最近更新 更多