在ColdFusion 10中使用CF_SQL_NVARCHAR的详细信息是什么?

时间:2012-05-29 15:42:52

标签: coldfusion coldfusion-10

关于更新数据库的ColdFusion 10文档有一节Database-related enhancements in ColdFusion 10。该页面提到现在支持CF_SQL_NVARCHAR,但没有关于它们的详细信息。此外,cfqueryparam documentation尚未更新以包含其存在。

ColdFusion 9 documentation for cfqueryparam提到CF_SQL_VARCHAR映射到MSSQL中的varchar。除非ColdFusion管理员datasource settings启用了String Format设置,否则这是真的。在这种情况下,CF_SQL_VARCHAR会映射到nvarchar。这个记录不完整的功能是一个hack,可以在ColdFusion中cause performance issues

所以他们引入CF_SQL_NVARCHAR非常棒,但了解它是如何工作的会很好。它只是CF_SQL_VARCHAR的别名,使其毫无意义?是否始终将字符串发送为nvarchar?如果是,CF_SQL_VARCHAR是否始终发送varchar

我希望为了向后兼容,它可以这样实现:

如果String Format已启用CF_SQL_VARCHARCF_SQL_NVARCHAR都已映射到nvarchar

如果String Format被停用,则CF_SQL_VARCHAR会映射到varcharCF_SQL_NVARCHAR会映射到nvarchar

这意味着任何CF10之前的网站都可以转移到CF10并运行,在CF10之前具有相同的性能考虑因素。

使用数据库设计重写所有查询以匹配CF_SQL_VARCHARCF_SQL_NVARCHAR的新网站或网站将不会获得CF10之前不可避免的性能损失。

任何人都可以确认是否是这种情况;如果有官方的东西会更好吗?

1 个答案:

答案 0 :(得分:12)

当你在等待更正式的事情时,我会投入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事件探查器确认)

    // 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事件探查器验证这一点。

最重要的是,到目前为止我所看到的一切都表明你对实施的目标是正确的。

    // 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 ','????? ??, ??? ??????? ????'