【问题标题】:SQL Array being returned as number, not String in ColdFusionSQL 数组作为数字返回,而不是 ColdFusion 中的字符串
【发布时间】:2010-11-18 05:18:31
【问题描述】:

在 Coldfusion 中,我使用一个 cfc 将一个选择框绑定到另一个选择框(基本上,从一个框中选择一个州,第二个框填充县名称。)县框的值是 5 位数字格式化为文本的数字(即值来自文本字段。)

问题是我发现如果所选县 id 的值以“0”开头,它就被切断了。

所以我得到了类似的东西: 爱德县 11223 一个 2300 B(应该是02300)

有人可以帮助确保前导 0 没有被截断吗?

这是页面上的选择框:

 <!--- State Name options --->
    <b>State:</b><br />
    <cfselect bind="cfc:states.getStates()" bindonload="true" name="search_state" id="search_state" value="StateUSAbb" display="StateName">
    </cfselect><br />

  <!--- County Name options --->
    <b>County:</b><br />
    <cfselect bind="cfc:states.getCounties({search_state})" name="search_county" id="search_county" value="FIPS_County" display="CountyName">
    </cfselect>

我讨厌粘贴整个 .cfc,但要注意后面的部分,尤其是使用 cfset 填充数组 RESULT 的 cfloop:

<cfcomponent output="false">

    <!--- Get array of media types --->
    <cffunction name="getStates" access="remote" returnType="array">
        <!--- Define variables --->
        <cfset var data="">
        <cfset var result=ArrayNew(2)>
        <cfset var i=0>

        <!--- Get data --->
        <cfquery name="data" datasource="bridges">
       SELECT DISTINCT tblLoc.StateUSAbb, lkuState.StateName
        FROM lkuState INNER JOIN tblLoc ON lkuState.FIPS_State = tblLoc.FIPS_State
        WHERE (lkuState.StateName <> 'New Brunswick')
        UNION
        SELECT '' AS StateUSAbb, ' ALL' AS StateName
        FROM lkuState
        ORDER BY StateName
        </cfquery>

        <!--- Convert results to array --->
        <cfloop index="i" from="1" to="#data.RecordCount#">
            <cfset result[i][1]=data.StateUSAbb[i]>
            <cfset result[i][2]=data.StateName[i]>
        </cfloop>

        <!--- And return it --->
        <cfreturn result>
    </cffunction>

    <!--- Get counties by state --->
    <cffunction name="getCounties" access="remote" returnType="array">
        <cfargument name="stateabb" type="string" required="true">

        <!--- Define variables --->
        <cfset var data="">
        <cfset var result=ArrayNew(2)>
        <cfset var i=0>

        <!--- Get data --->
        <cfquery name="data" datasource="bridges">
        SELECT '' AS FIPS_COUNTY, ' ALL' as CountyName
        FROM lkuCnty
        UNION
        SELECT FIPS_County, CountyName
        FROM lkuCnty
        WHERE StateAbb = '#ARGUMENTS.stateabb#'
        ORDER BY CountyName
        </cfquery>

        <!--- Convert results to array --->
        <cfloop index="i" from="1" to="#data.RecordCount#">
            <cfset result[i][1]=data.FIPS_County[i]>
            <cfset result[i][2]=data.CountyName[i]>
        </cfloop>

        <!--- And return it --->
        <cfreturn result>
    </cffunction>

</cfcomponent>

【问题讨论】:

  • 您使用的是哪个版本的 ColdFusion?
  • 这个错误与JSON的序列化方式有关。

标签: sql arrays coldfusion cfc


【解决方案1】:

如果数据是固定长度,您可以使用 NumberFormat 强制前导零。通常,CF 是无类型的,因此必须发生一些导致数据损坏的底层转换。您可以尝试强制值 toString(),或者调试添加单引号作为列值中的第一个字符(例如 SELECT '''' + FIPS_County, '''' + CountyName FROM lkuCnty)以查看是否他们保留了所有角色。

[更新] 根据您的 cmets 关于 SQL 未返回 5 个字符的原因,使用此更新后的查询从 INT 转到带有前导零的 VARCHAR。

  SELECT DISTINCT 
    RIGHT('00000' + CONVERT(VARCHAR(5),StateUSAbb),5), 
    lkuState.StateName
         FROM lkuState INNER JOIN tblLoc ON lkuState.FIPS_State = tblLoc.FIPS_State
         WHERE (lkuState.StateName <> 'New Brunswick')
  UNION
     SELECT '' AS StateUSAbb,
     ' ALL' AS StateName
          FROM lkuState
          ORDER BY StateName

【讨论】:

  • 我尝试使用 cfset result[i][1]=toString(data.FIPS_County[i])。没有运气。
  • 您需要在选择的输出或数组的分配中查明数据丢失的位置。您是否尝试添加单引号以查看它是否来自 SQL?
  • 我一直在 Firebug 中查看此内容。当我从选择框中选择一个州时,会填充县框中的值,例如:[25001.0,"Barnstable"]。因此,一个数字。但是页面上的其余操作仍然有效。下一个查询只使用“25001”。如果我选择一个县代码带有前导零的州,我会得到如下内容:[6023.0,"Humboldt"]。至少,Firebug 是这样显示的。如果我将 sql 更改为 SELECT ' ' + FIPS_County,Firebug 会显示诸如“6023”之类的值。看起来像带有前导空格的文本。我需要一些逻辑来修剪和添加 0...?
  • 啊... SELECT " " + FIPS_County(双引号)抽回 ["06023","Humboldt"]。更好的!所以,我想我只需添加一个 Trim,如下所示:cfset result[i][1]=Trim(data.FIPS_County[i])。突然间,Firebug 吐出诸如 [6023.0,"Humboldt"] 之类的东西。又是数字。天哪...
  • 我想我明白了。我把 LTrim 放错了位置。不想在数组中设置它,我只是把它放在 sql 代码中,用于下一个采用 County_FIPS 的查询。即:tblLoc.FIPS_County = LTrim()。我认为这现在可行。
【解决方案2】:

在数字的末尾添加一个空格,然后CF会将其视为一个字符串,并且不会截断前导0。

简单的解决方法:&lt;cfset result[i][1]=data.StateUSAbb[i] &amp; " "&gt;

顺便说一句,您知道填充cfselect 支持查询对象吗?所以你甚至不需要循环。您可以在 cfquery 中的 SQL 中执行相同的解决方法

更新: 无论如何,想法是,如果您想保留前导 0 并继续使用 CF 内置的 serializeJSON() 或以 JSON 样式调用 cfc 远程方法(这将在内部调用 serializeJSON (),您可以附加一个空格,以便 CF 将其视为一个字符串并保留前导 0。如果您的脚本以某种方式必须需要没有尾随空格的“012345”,那么从 riaforge 或 cflib 寻找另一个 JSON 序列化程序。

【讨论】:

  • 老兄。没用。我将这一行更改为: cfset result[i][1]=data.FIPS_County[i] & " " (您将空引号附加到错误的变量中)。无论如何,它对结果没有任何影响。同样的事情也会发生。
  • 所以您希望 data.FIPS_County 被格式化为字符串,对吗?查看 firebug 中的 JSON,查看 FIPS_County 的格式是否类似于 FIPS_County:"0123" 或 FIPS_County:123
  • 当我在 CF 中进行调试时,它显示 FIPS_County 的参数 #2(CF_SQL_VARCHAR) = 25011 没有前导 0。参数 #2(CF_SQL_VARCHAR) = 6023 它应该在哪里( 06023)。我不确定我是否在 Firebug 中寻找正确的位置(Net > XHR > Get States.cfc?method=getCounties .....):在“响应”下它只显示 [[“”,“全部"]]。这将是 SQL 的第一部分(其余部分是联合的)。但即使对于一个没有领先 0 的县,我也看到了同样的情况。所以也许我没找对地方?
  • 当我在 CF 中进行调试时,它显示 FIPS_County 的参数 #2(CF_SQL_VARCHAR) = 25011 没有前导 0。参数 #2(CF_SQL_VARCHAR) = 6023 它应该在哪里( 06023)。我不确定我是否在 Firebug 中寻找正确的位置(Net > All > Post..> search_county 6023
  • 谢谢,但是您对 JSON 序列化程序的建议有点超出我的理解范围,所以我不知道如何实施该建议。
【解决方案3】:

您确定查询返回的数据是包含前导零的文本字符串,而不仅仅是整数值?无论如何,我认为 Zachary 对 NumberFormat(x, "00000") 的建议是可行的方法。

【讨论】:

  • 不确定为什么它不是文本字符串。毕竟,fieldtype 是一个数字(双精度)。并且正在使用的值被插入到另一个带有 cfsqltype="CF_SQL_VARCHAR" 的 cfqueryparm 标记的 cfquery 中,除了前导 0 不存在之外,它工作正常。希望在实施此建议方面提供更多帮助,但我很担心。为什么我要将其格式化为数字?这会将其更改为字符串中的数字吗?同样,它必须是一个字符串。谢谢。
  • 还尝试了 cfset result[i][1]= NumberFormat(data.FIPS_County[i], "00000"。相同的结果。对没有前导零的 County_FIPS 很好。对其他人没有好处前导 0。
猜你喜欢
  • 1970-01-01
  • 2016-09-28
  • 2019-08-20
  • 2011-09-20
  • 1970-01-01
  • 2021-02-11
  • 1970-01-01
  • 2019-01-19
  • 1970-01-01
相关资源
最近更新 更多