Cf-script 将查询结果转换为具有唯一键的结构?

Cf-script convert query result in structure with the unique key?

我的系统中几乎没有函数需要从 CFML 转换为 CFSCRIPT。在处理这个项目时,我 运行 我的结构输出的结果(很多空行)比它应该的多,甚至只查询 return 一行。这是我在 CFSCRIPT 中的代码示例:

cfstoredproc( procedure="GetZip", datasource=Application.dsnRead ) {
    cfprocparam( dbvarname="@Zip", value=trim(52401), cfsqltype="cf_sql_char", maxlength=5 );
    cfprocresult( name="ZipResult" );

}

local.strZip = {};
strZip[ZipResult.RecID] = {
    "City" : trim(ZipResult.City),
    "State" : trim(ZipResult.State)
};

writeDump(strZip);

这是我得到的输出结果:

array
1   [undefined array element]
2   [undefined array element]
3   [undefined array element]
4   [undefined array element]
5   [undefined array element]
6   [undefined array element]
7   [undefined array element]
8   [undefined array element]
9   [undefined array element]
10  [undefined array element]
11  [undefined array element]
12  [undefined array element]
13  [undefined array element]
14  [undefined array element] 
...

我想知道在结构中输出查询结果并使用 RecID 作为唯一键的最佳方法是什么?这个例子和上面的查询总是 return 1 条记录,但我也想知道如果我需要用多条记录循环查询结果,这段代码将如何工作?

更新:我想我找到了问题所在。 RecID 是我的数据库 table 中的自动递增 ID。例如,当 i return RecID 时,值可以是 56743。因此,如果我将 RecID 作为键传递到我的结构中,那将导致结构中出现如此多的行。我的问题是如何防止这种情况发生?有没有办法只设置密钥?

你可以试试这个 -

    var strZip = {};
    for ( i=1; i<=ZipResult.recordCount; i++)
    {
        strZip[ZipResult.RecID[i]] = {
             "City" : trim(ZipResult.City[i]),
             "State" : trim(ZipResult.State[i])
        };
    }

通过这种方式,我们将查询视为数组结构。

不,你是对的。因为它是一个整数,所以 ColdFusion 将填充数组直到该整数的点,因为你不能有一个包含一堆空值的数组;他们必须有一些价值,所以——正如你在这里看到的——他们是未定义的。 您不能将整数用作结构键。如果您在它的前面添加一个字母,然后在引用它时将键截断为该值,那将起作用。这很老套,但这就是我通常为这类事情所做的。 如果你想测试它,你可以使用 StructInsert() 而不是 [].

我不确定为什么您的 CF 将 strZip 转换为数组,但这就是您得到一堆空数组的原因。结构键可以是整数,但是当您告诉数组插入 x[42] 时,您的数组中将有 42 个元素。 local.strZip = {}; 非常明确地指出 strZip 是一个结构。但是,有时 CF 中的作用域会变得很奇怪。根据您使用它的方式,我认为当您执行 strZip[ZipResult.RecID] 时,它可能会创建一个新的无作用域变量,它是一个数组。然后当你转储它时,你正在转储 strZip 的数组版本。您可以尝试使用 local.strZip[ZipResult.RecID] 并查看是否会改变您的行为。或尝试转储 local.strZip 并查看它是否为空。

或者你可以这样做:

<cfscript>
    // Build a fake query object.
    ZipResult = queryNew(
        "RecID, City, State",
        "integer, varchar, varchar",
        [
              { RecID: 99, City: "Nashville", State: "TN" }
        ]
    );
    writeDump(ZipResult); // What's in our query?


local.strZip = {
    "#ZipResult.RecID#" : {
      City : trim(ZipResult.City) , 
      State : trim(ZipResult.State)
    }
};

writeDump(strZip);

</cfscript>

https://trycf.com/gist/28440630b0aa7ba1642e45bab3503652/acf2016?theme=monokai

注意:我无法在 TryCF 中复制您的行为,但我也不太可能在与您相同的范围内执行该代码。 确认:https://cffiddle.org/app/file?filepath=50f4e710-bd9b-40dd-a03a-15695bdd5a0d/c476f91b-6931-4295-be67-e4309aecfa0c/0492a7c6-029f-4227-941a-faee9da5a7cc.cfm