возможно ли динамически создать запрос и экранировать значения, используя cfscript cfquery cfqueryparam?

#coldfusion #concatenation #coldfusion-8

#coldfusion #конкатенация #coldfusion-8

Вопрос:

Я все еще новичок в ColdFusion. По сути, я динамически создаю запрос для Oracle. В прошлом я использовал cfquery / cfparam, но я бы предпочел использовать cfscript для выполнения, поскольку это более читабельно. Предполагается, что это будет большой ‘ВСТАВИТЬ ВСЕ … В.’

Вот базовый пример того, что у меня есть на данный момент:

 <cfscript>
clinicNIL = structNew();
clinicNIL.ADDRESS1 = 'line 1';
clinicNIL.ADDRESS2 = 'line 2';

myFields = [
     'ADDRESS1'
    ,'ADDRESS2'
];

query = queryNew("");
sql = "INSERT ALL";

for (i=1; i LTE ArrayLen(myFields); i=i 1) {

    sql = sql amp; "INTO NOTINLIST (SOURCETABLE, SOURCECOLUMN, SOURCEPK, ENTEREDVALUE, INSERTDATE, UPDATEDDATE, INSERTEDBY, UPDATEDBY) VALUES(";
    // [..]

    // How to dynamically escape the value below?
    sql = sql amp; EscapeTheParameterHere( clinicNIL[ myFields[i] ]);

    // [..]
    sql = sql amp; ")
";

}

WriteOutput( query );
</cfscript>
  

Где у меня есть ‘EscapeTheParameterHere’, я хочу иметь возможность каким-то образом экранировать это значение. как я могу экранировать значение?

пока я здесь, есть ли какие-нибудь хорошие ресурсы или ссылки для CF?

Комментарии:

1. Я думаю, что старый добрый cfquery был бы более читабельным

Ответ №1:

Вы можете привязать параметры, используя функцию addParam объекта запроса cfscript, точно так же, как работает cfqueryparam. Пришлось немного преобразовать ваш пример для работы с моим блоком MSSQL и уменьшенной версией вашей таблицы, но это должно дать вам общую идею.

 <cfscript>
clinicNIL = structNew();
clinicNIL.ADDRESS1 = 'line 1';
clinicNIL.ADDRESS2 = 'line 2';

myFields = [
     'ADDRESS1'
    ,'ADDRESS2'
];

query = new query();
//you may need to use the query methods setDatasource, setUsername and setPassword to configure the query

//sql = "INSERT ALL" amp; chr(13) amp; chr(10);
sql = "";

for (i=1; i LTE ArrayLen(myFields); i=i 1) {

    query.addParam(name="address"amp;i,value=clinicNIL[ myFields[i] ],cfsqltype="VARCHAR");

    sql = sql amp; "INSERT INTO NOTINLIST (ADDRESS) VALUES(";

    sql = sql amp; ":address" amp; i;

    sql = sql amp; ")" amp; chr(13) amp; chr(10);

}

queryResult = query.execute(sql=sql);
</cfscript>
  

Волшебство заключается в том, что :paramName в строке sql соответствующий параметр будет заменен во время вызова execute соответствующим экранированным параметром.

Комментарии:

1. Просто примечание к OP: это предполагает CF-.

2. аааа! Я думал, что я заявил, что использую Coldfusion 8, но я только пометил его как это. есть ли способ сделать это в CF8?? К сожалению, вышеуказанное не работает для CF8… :-

3. @Clayton Боюсь, что нет, это было добавлено с CF9, чтобы дополнить некоторые из недостающих тегов в CFSCRIPT. Для CF8 вам придется использовать CFQUERY и CFQUERYPARAM.

Ответ №2:

вот решение, которое я придумал, используя cfquery / cfqueryparam. Я не знал, что вы могли бы выполнить cfloop внутри cfquery. Кстати, я нашел что-то под названием ‘CF.Запрос’ но, по-видимому, он удовлетворяет только подмножеству cfquery.

 <cfscript>
clinicNIL = structNew();
clinicNIL.ADDRESS1 = 'line 1';
clinicNIL.ADDRESS2 = 'line 2';

myFields = [
     'ADDRESS1'
    ,'ADDRESS2'
];

totalFields = ArrayLen(myFields);

</cfscript>
<cfquery name="insert" datasource="somedatasource">
    INSERT ALL
    <cfloop from="1" to="#totalFields#" index="i">
            INTO NOTINLIST 
            (SOURCETABLE, SOURCEPK, SOURCECOLUMN, ENTEREDVALUE, INSERTDATE, UPDATEDATE, INSERTEDBY, UPDATEDBY) 
            VALUES(
             'FACULTYADDRESSES'
            , 123
            , <cfqueryparam value = "#myFields[i]#" cfsqltype='CF_SQL_VARCHAR'>
            , <cfqueryparam value = "#clinicNIL[ myFields[i] ]#" cfsqltype='CF_SQL_VARCHAR'>
            , SYSDATE
            , SYSDATE
            , '123'
            , '123'
            )
    </cfloop>
    SELECT * FROM DUAL
</cfquery>