使用脚本循环更新查询

时间:2012-10-22 18:18:27

标签: coldfusion railo cfml

尝试弄清楚如何使用脚本执行此循环。

<cfquery>
<cfloop from="1" to="#arrayLen(myData)#" index="i">
<!--- update query with different paramaters --->
</cfloop>
</cfquery>

我可以在外面循环,就像这样,但它很慢:

for(i=1; i LTE arrayLen(myData); i++)
{
    q = new Query();
    q.setSql(" UPDATE SQL HERE ");
    q.addParam(name="id", value=i);
    q.Execute().GetResult();
}

我想在SQL中做,而不是在SQL之外。

更新: 这是代码。我试图删除其中的一些以使其更简单。

我有一个用户输入数据的表单,然后调用它:

for(i=1; i LTE listlen(arguments.myStruct.myfield1); i++)   {           
    myfield1 = listgetAt(arguments.myStruct.myfield1,i);

    for(j=1; j LTE arguments.myStruct.count; j++) {
        maxvalue = form["max" & j];
        myType = form["myType" & j];
        id = myfield1;

        local.queryService = new Query();
        local.queryService.setSql
        ("          
            UPDATE  mytypes
            SET     maxvalue = :maxvalue,
                    myType = :myType
            WHERE   mytypeID = :id
        ");
        local.queryService.addParam(name="id", value=id);
        local.queryService.addParam(name="maxvalue", value=maxvalue, cfsqltype="cf_sql_integer");
        local.queryService.addParam(name="myType", value=myType, cfsqltype="cf_sql_integer");
        local.queryService.Execute().GetResult();
    }
}

3 个答案:

答案 0 :(得分:1)

重新阅读Adam's response后,我同意我们需要查看原始更新查询。我不是100%确定你的目标是什么,但这是我的“猜测”。如果要更新具有不同值的多个记录,例如:

   UPDATE Table Col = 'xxx' WHERE ID = 1 ;
   UPDATE Table Col = 'yyy' WHERE ID = 2 ;
   ...

..你可以构建字符串并在循环中添加参数。请参阅以下适应Adam的例子。注意,您需要在数据源中启用“允许多个查询”设置才能使其正常工作。此外,请务必将execute()调用包装在事务中以维护数据完整性。

编辑根据您的更新修改了上一个示例:

<cfscript>
    // initialize these before any looping
    q = new Query();
    q.setDatasource("yourDSNHere");

    sqlArray = [];

    for(i=1; i LTE listlen(arguments.myStruct.myfield1); i++)   {           
        id = listgetAt(arguments.myStruct.myfield1,i);

        for(j=1; j LTE arguments.myStruct.count; j++) {
           // extract input values
           maxValue = form["max" & j];
           myType = form["myType" & j];

           // append a new statement
           arrayAppend(sqlArray, "UPDATE  mytypes 
                                  SET     maxvalue  = ?
                                        , myType = ? 
                                  WHERE myTypeID= ? "
                         );

           // add in the parameter values
           q.addParam(value="#maxValue#", cfSqlType="cf_sql_integer");
           q.addParam(value="#myType#", cfSqlType="cf_sql_integer");
           q.addParam(value="#id#", cfSqlType="cf_sql_integer");
    }

    // finally convert to single SQL string and run it
    q.setSQL( arrayToList(sqlArray, ";") );
    q.execute();
</cfscript>

答案 1 :(得分:0)

我不太清楚你需要在循环中使用什么样的信息,但是这样做的一种方法是构建你的更新语句,然后在你的cfquery中输出它。这是在cfscript中执行此操作的另一种方法:

<cfscript>
myData = ArrayNew(2);

myData[1][1] = "test";

myData[1][2] = "1";

for (row = 1; row LTE ArrayLen(myData); row++) {

    queryService = new query(); 

    queryService.setSQL('UPDATE mytable SET myfield = "#myData[row][1]#" where table_id=#myData[row][2]#');

    result = queryService.execute();
}
</cfscript>

答案 2 :(得分:0)

很难说出你实际问的是什么,但这可能是答案呢?

<cfscript>
// dunno what your data is, but you need a col and a value so let's pretend you have those
myData = [
    {col="col1", value="one"},
    {col="col2", value="two"},
    {col="col3", value="three"}
];      


q = new Query(datasource="scratch_mysql");

sql = "UPDATE tbl_test2 SET ";
for (i=1; i <= arrayLen(myData); i++){
    q.addParam(value=myData[i].value);  // you might want a type here as well?
    sql &= " #myData[i].col# = ?";
    if (i < arrayLen(myData)){  
        sql &= ",";
    }
}
sql &= " WHERE id=1";

q.setSql(sql);
q.execute();
</cfscript>

我会投票给你,直到你让问题更清楚。这是第一个需要澄清的<cfquery>位:你现在正在做什么。如果我们知道这一点,我们就会知道如何用脚本告诉你如何做到这一点。