2016-06-06 5 views
0

Я работаю в Cold Fusion 11 *, и я получаю следующее сообщение об ошибке:запросов - строковый литерал Too Long ORA Ошибка

ORA-01704: string literal too long. 

Во-первых, я получил эту ошибку и исправить ее после того, как глядя на нескольких сайтах по меняю код из:

<cfquery datasource="#dsn#"> 
    update paragraphs 
    set paragraph_text = #input# 
    where paragraph_id=#rs_d.paragraph_id# 
</cfquery> 

To:

<cfquery datasource="#dsn#"> 
    update paragraphs 
    set paragraph_text = <cfqueryparam cfsqltype="CF_SQL_CLOB" value=#input#> 
    where paragraph_id=#rs_d.paragraph_id# 
</cfquery> 

Это исправление работало отлично. Теперь я получаю ту же ошибку, но вместо использования cfquery, я делаю запрос sql в строку перед тем, как работать с ним. Так вот как выглядит код:

sql = "insert into log (LOG_ENTRY_ID, program_id, paragraph_id, action, userid,"; 
sql = sql & " paragraph_text_old, paragraph_text_new, comment_id, current_program_status, new_program_status)"; 
sql = sql & " values (1 ," & program_id & ","; 
if (paragraph_id neq ""){ 
    sql = sql & paragraph_id & ","; 
} 
else{ 
    sql = sql & " null,"; 
} 
sql = sql & "'" & action & "',"; 
sql = sql & userid & ", '"; 
sql = sql & DoubleSingleQuotes(paragraph_text_old) & "','"; 
sql = sql & DoubleSingleQuotes(paragraph_text_new) & "',"; 
if (comment_id neq ""){ 
    sql = sql & comment_id & ","; 
} 
else{ 
    sql = sql & " null,"; 
} 
if (current_program_status neq ""){ 
    sql = sql & "'" & current_program_status & "',"; 
} 
else{ 
    sql = sql & " null,"; 
} 
if (new_program_status neq ""){ 
    sql = sql & "'" & new_program_status & "'"; 
} 
else{ 
    sql = sql & " null"; 
}  
sql = sql & ")"; 
    cfstmt(sql); 

--- Конец функция

<cffunction name="cfstmt"> 
    <cfargument name="sql"> 
    <cfquery name="rs" datasource="#dsn#"> 
     #PreserveSingleQuotes(sql)# 
    </cfquery> 
</cffunction> 

Причина ошибки old_paragraph_text и new_paragraph_text. Мне было интересно, можно ли включить решение типа cfqueryparam в эту проблему, как в предыдущей проблеме/решении, которое я включил. Я попытался включить его прямо как первый, но я получаю ошибки компиляции в коде. Любые мысли или советы были бы полезны, спасибо.

+0

* попробовал включить его прямо как первый, но я получаю ошибки компиляции * Можете ли вы опубликовать фрагмент кода, который вы пробовали? Он должен работать нормально, пока вы используете ['Query' и' addParam() '] (http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSe9cbe5cf462523a0693d5dae123bcd28f6d-7ffb.html) ИЛИ преобразовали код к cfml/cfquery. – Leigh

+0

Это то, что я пробовал, как только я снова запустил программу. Я отправлю сообщение об ошибке, я мог бы форматировать заявление неправильно. Я попытаюсь снова добавить это. @Leigh sql = sql & & "','"; – Chris

+1

Вы не можете использовать cfqueryparam как часть такой переменной. Кроме того, при использовании параметров запроса вам не нужно удваивать одиночные кавычки. –

ответ

1

(слишком долго для комментариев)

wanted to limit the code so instead of determining the null value outside the query, I added the case statements

Честно говоря, это не спасёт много, так как код, по существу, делает Условный/еще так или иначе. Кроме того, работа выполняется на стороне db, а не на сервере приложений, где он принадлежит.

Работая с множеством устаревших приложений, я понимаю, что они часто включают в себя то, что вы могли бы эвфемистически назвать «сомнительным» кодом ;-) Однако вы должны никогда не использовать необработанные клиентские переменные в SQL. Если у вас нет веских оснований для этого, всегда используйте cfqueryparam.

Внутренний, cfqueryparam использует bind variables. Два из наиболее важных преимуществ являются:

  1. Bind переменных помогают защитить от sql injection, предотвращая буквальное значение от выполняются в виде команд SQL. Это защищает базу данных от значений, содержащих вредоносный SQL.

  2. Для запросов, выполняемых несколько раз, связывание переменных также повышает производительность за счет поощрения базы данных к повторному использованию планов выполнения. В противном случае база данных может выбрать создание нового плана выполнения при изменении параметров запроса, что является дорогостоящим.

CFQueryparam также имеет некоторые другие приятные функции, такие как атрибут «null». Он может использоваться для подачи значения null при выполнении определенных условий.

И, наконец, с точки зрения передового опыта, это также хорошая идея, чтобы полностью охватить все переменные. Например, если переменные представлены в области FORM, окончательный запрос может выглядеть что-то вот так. (Изменение cfsqltypes по мере необходимости.)

<cfquery datasource="#variables.dsn#"> 
    INSERT INTO into log (
    program_id 
    , paragraph_id 
    , userid 
    , action 
    , paragraph_text_old 
    , paragraph_text_new 
) 
VALUES 
(
    <cfqueryparam value="#FORM.program_id#" cfsqltype="CF_SQL_INTEGER"> 
    , <cfqueryparam value="#FORM.paragraph_id#" cfsqltype="CF_SQL_INTEGER" null="#NOT IsNumeric(FORM.paragraph_id)#"> 
    , <cfqueryparam value="#Session.userid#" cfsqltype="CF_SQL_INTEGER"> 
    , 'Paragraph Updated' 
    , <cfqueryparam cfsqltype="CF_SQL_CLOB" value="#rs_d.paragraph_text#"> 
    , <cfqueryparam cfsqltype="CF_SQL_CLOB" value="#FORM.input#"> 
) 
</cfquery> 

NB: Если столбец не имеет другое значение по умолчанию назначались, NULL будет вставлен автоматически, если этот столбец исключается из INSERT списка.

+0

Спасибо за детали и объяснения – Chris

1

Я предлагаю переустановить вашу логику, чтобы определить переменные field null, которые затем будут использоваться в нулевом атрибуте cfqueryparam. Что-то вроде этого:

<cfscript> 
fieldOneNull = conditionForNull ? true : false; 
fieldTwoNull = conditionForNull ? true : false; 
etc 
</cfscript> 

<cfquery> 
insert into table 
(field1, field2, etc) 
values 
(
<cfqueryparam cfsqltype="cf_sql_whatever" value="something" null="#fieldOneNull#"> 
, <cfqueryparam cfsqltype="cf_sql_whatever" value="something" null="#fieldTwoNull#"> 
, etc 
) 
+0

Спасибо за предложение, я взял аналогичный маршрут, но я хотел ограничить код, поэтому вместо определения нулевого значения вне запроса я добавил утверждения case. – Chris

0

Спасибо за предложения. Вместо изменения существующей функции, которая используется в разных областях приложения, я добавил новую инструкцию insert в позицию, в которой функция вызывалась для работы с клобами. Для обработки нулевых полей я использовал оператор case.

<cfquery datasource="#dsn#"> 
    insert into log (
     LOG_ENTRY_ID, program_id, paragraph_id, userid, action, paragraph_text_old 
     , paragraph_text_new, comment_id, current_program_status, new_program_status 
    ) 
    values (
     null ,#program_id#,(case when #paragraph_id# = '' then null else #paragraph_id# end) 
     , #Session.userid# , 'Paragraph Updated' 
     , <cfqueryparam cfsqltype="CF_SQL_CLOB" value=#rs_d.paragraph_text#> 
     , <cfqueryparam cfsqltype="CF_SQL_CLOB" value=#input#> 
     , null, null , null 
    ) 
</cfquery> 
+0

Также я пробовал модифицировать существующую функцию, но я все время сталкивался с отсутствующей ошибкой оракула. (Я использовал ту же формулировку, что и в ответе, но я думаю, что переменные могли быть связаны по-другому или что-то в этом роде. – Chris

Смежные вопросы