Подтвердить что ты не робот

Каковы детали использования CF_SQL_NVARCHAR в ColdFusion 10?

Документация ColdFusion 10 по обновлению базы данных содержит раздел Усовершенствования, связанные с базой данных в ColdFusion 10. На этой странице упоминается, что теперь есть поддержка CF_SQL_NVARCHAR среди других, но без каких-либо подробностей о них. Кроме того, документация cfqueryparam не была обновлена, чтобы включить их существование.

Документация ColdFusion 9 для cfqueryparam упоминает, что CF_SQL_VARCHAR отображается в varchar в MSSQL. Это верно, если только администратор ColdFusion параметры источника данных не включил параметр String Format. В этом случае CF_SQL_VARCHAR отображается на nvarchar. Эта плохо документированная функция - это взлом, который может вызывать проблемы с производительностью в ColdFusion.

Так здорово, что они представили CF_SQL_NVARCHAR, но было бы хорошо понять, как это работает. Это просто псевдоним для CF_SQL_VARCHAR, что делает его бессмысленным? Всегда ли он отправляет строки как nvarchar? Если да, то CF_SQL_VARCHAR всегда отправляет varchar?

Я надеюсь, что для обратной совместимости он реализован как таковой:

Если String Format включен CF_SQL_VARCHAR и CF_SQL_NVARCHAR, оба отображаются на nvarchar.

Если String Format отключено, то CF_SQL_VARCHAR отображается на varchar и CF_SQL_NVARCHAR на nvarchar.

Это означало бы, что любые сайты pre-CF10 могут перейти на CF10 и работать с одинаковыми соображениями производительности pre-CF10.

Новые сайты или сайты, которые переписывают все запросы в соответствии с CF_SQL_VARCHAR и CF_SQL_NVARCHAR с дизайном базы данных, не получат ограничение производительности, которое неизбежно пре-CF10.

Может ли кто-нибудь подтвердить, если это так; еще лучше, если с чем-то официальным?

4b9b3361

Ответ 1

Пока вы ждёте что-то более официальное, я заберу $0,02...

Я сделал некоторые копания и основываясь на своих наблюдениях (с источником данных MS SQL), я считаю, что:

  • CF_SQL_NVARCHAR - это не просто псевдоним для CF_SQL_VARCHAR. Он сопоставляется с новым NVARCHAR jdbc type, который позволяет обрабатывать значения unicode на более узком уровне.

  • CF_SQL_NVARCHAR значения всегда рассматриваются как nvarchar

  • Обработка CF_SQL_VARCHAR зависит от параметра String Format, как и в предыдущих версиях.

CF_SQL_NVARCHAR Тест/результаты:

Если вы включите ведение журнала данных, вы увидите, что при каждом использовании CF_SQL_NVARCHAR драйвер вызывает специальный метод setNString. Поэтому в конечном итоге значение отправляется в базу данных как nvarchar. (Вы можете подтвердить это с помощью SQL Profiler)

    // Query
    SELECT  ID
    FROM    Test
    WHERE   NVarcharColumn = <cfqueryparam value="#form.value#" cfsqltype="cf_sql_nvarchar">

    // Log 
    spy(...)>> PreparedStatement[9].setNString(int parameterIndex, String value)

    // Profiler
    exec sp_prepexec @p1 output,N'@P1 nvarchar(4000)',N'SELECT  ID
            FROM    Test
            WHERE   NVarcharColumn = @P1 ',N'Стоял он, дум великих полн'

CF_SQL_VARCHAR Тест/Результаты:

В случае CF_SQL_VARCHAR он технически помечен как varchar. Тем не менее, параметр String Format в конечном итоге контролирует, как он обрабатывается базой данных. Когда настройка включена, она обрабатывается как nvarchar. Когда он отключен, он рассматривается как varchar. Опять же, вы можете проверить это с помощью SQL Profiler.

В нижней строке, все, что я видел до сих пор, говорит, что вы правы на цели реализации.

    // Query
    SELECT  ID
    FROM    Test
    WHERE   PlainVarcharColumn = <cfqueryparam value="#form.value#" cfsqltype="cf_sql_varchar">

    // Log
    spy(..)>> PreparedStatement[8].setObject(int parameterIndex, Object x, int targetSqlType)
    spy(..)>> parameterIndex = 1
    spy(..)>> x = ????? ??, ??? ??????? ????
    spy(..)>> targetSqlType = 12  (ie CF_SQL_VARCHAR)

    // Profiler (Setting ENABLED)
    exec sp_prepexec @p1 output,N'@P1 nvarchar(4000)',N'SELECT  ID
            FROM    Test
            WHERE   PlainVarcharColumn = @P1 ',N'Стоял он, дум великих полн'

    // Profiler (Setting DIS-abled)
    exec sp_prepexec @p1 output,N'@P1 varchar(8000)',N'SELECT  ID
            FROM    Test
            WHERE   PlainVarcharColumn = @P1 ','????? ??, ??? ??????? ????'