Coldfusion Query of Query 运行时错误,不支持将类型转换为 NULL。

huangapple go评论42阅读模式
英文:

Coldfusion Query of Query runtime error, Casting to type NULL is unsupported

问题

作为概念验证,我试图将一个结构数组转换成一个查询对象,以便我可以使用SQL和查询查询来查询它。我可以使用queryNew()将结构数组转换成查询对象:

<cfset qTest = queryNew(things)>

我发现可以使用cfdump对其进行输出,但无法查询它:

<cfquery name="myQuery" dbtype="query">
     SELECT *
     FROM qTest
</cfquery>

因为我遇到了这个错误:

查询查询运行时错误。
不支持的强制转换异常:不支持到NULL类型的强制转换。

在查找这个错误并看到其他人遇到的问题后,我认为这与以下事实有关:当您以这种方式创建自定义查询(即,仅提供结构数组给queryNew(),而不提供列名或数据类型列表)时,查询对象会将结构键解释为列名,并假设适当的数据类型。

作为一次实验,我只包含了数组中的前十个结构(或行,如果您愿意),将数组传递给queryNew(),并且查询查询没有问题。我逐渐增加了行数,直到达到第130行,然后再次遇到了该错误消息。如果数组只包含1-129行,则没有问题,但是当我添加第130行时,就会出现错误消息。因此,我认为第130行必须是问题所在。但是,如果我只包括行120-130,我就没有问题。如果我只包括行100-130,也没有问题。但是,如果我包括行90-130,我会再次收到错误消息。

所以我想,随着行数的增加,CF最终会决定分配一个不同的数据类型,一个触发“不支持强制转换到NULL类型”的数据类型,当包括第130行时。显而易见的解决方法通常是在queryNew()中包含列名和数据类型列表作为参数,但是由于几个原因,在我的情况下不太切实际。首先,这是一个非常长的列名列表(62个)。其次,这非常不灵活;这个结构数组最终来自API的数据,如果列名列表稍有变化,我的代码就会出错。

所以我想知道是否有其他方法可以防止“不支持强制转换到NULL类型”的错误。或者,是否有一种方法可以输出CF分配给每个列的数据类型。否则,如果我不能使用SQL以查询格式处理这些数据,那么必须循环遍历结构数组来查找和提取所需的数据将会非常繁琐。看起来这正是Adobe增强了queryNew()的目的,以便能够接受结构数组作为参数的整个原因。

我本来想包含一些示例数据,但查询有62列。我希望这是一个已知问题,并且有一个已知的解决方法 - 谢谢。

英文:

As a proof of concept, I'm trying to convert an array of structs into a query object, so that I can query it using SQL and query of query. I'm able to convert the array of structs into a query object using queryNew():

&lt;cfset qTest = queryNew(things)&gt;

And I'm finding that I can cfdump it, but I can't query it:

&lt;cfquery name=&quot;myQuery&quot; dbtype=&quot;query&quot;&gt;
     SELECT *
     FROM qTest
&lt;/cfquery&gt;

Because I'm getting this error:

Query Of Queries runtime error.
Unsupported Cast Excpetion: Casting to type NULL is unsupported.

After Googling this error and seeing issues some others have had, I believe this has to do with the fact that when you create a custom query this way (i.e., supplying only an array of structs to queryNew(), without the column list or data type list), then the query object interprets the struct keys as column names and assumes the appropriate data type.

As an experiment, I included only the first ten structs (or rows, if you like) in the array, fed the array to queryNew(), and had no problems with querying the query. I increased the number of rows until I got up to row 130, and then I got that error message again. No problems if the array had rows only 1-129, but error message when I added row 130. So I thought row 130 must be the problem row. But then, if I include only rows 120-130, I have no problems. If I include only rows 100-130, no problems. But if I include rows 90-130, I get the error message again.

So I figure that as I increased the number of rows, eventually CF decides to assign a different datatype, one that triggers that "casting to type NULL is unsupported" when row 130 is included. The obvious workaround would normally be to include the column list and datatype list as arguments in queryNew(), but that's impractical in my case for a couple of reasons. One, it's a very long column list (62). Two, that's very inflexible; this array of structs is ultimately coming from data from an API, and if the column list were ever to change at all, my code would break.

So what I'm wondering is if there's any other way to prevent that "Casting to type NULL is unsupported" error. Or, if there's a way to output what data types CF is assigning to each column. Else, if I can't work with this data in query format using SQL, it's going to be very cumbersome having to loop through arrays of structs to find and pull out the data I want. Seems that's the whole reason why Adobe enhanced queryNew() to be able to accept an array of structs as an argument in the first place.

I would include some sample data, but the query has 62 columns. I'm hoping this is a known issue with a known workaround -- thanks.

答案1

得分: 2

正如 @EddieLotter 指出的,有许多种方法可以仅使用数组函数来解决这个问题。例如,这里是自 ACF 10 起就存在的 ArrayFilter

https://helpx.adobe.com/coldfusion/cfml-reference/coldfusion-functions/functions-a-b/arrayfilter.html

来自他们示例的代码:

superheroes=[
      {"name":"Iron Man","member":"Avengers"},
      {"name":"Wonder Woman","member":"Justice League"},
      {"name":"Hulk","member":"Avengers"},
      {"name":"Thor","member":"Avengers"},
      {"name":"Aquaman","member":"Justice League"}
];
avengers=ArrayFilter(superheroes,function(item){
      return item.member=="Avengers";
});
writeDump(avengers);

这将输出包含键 member 值为 Avengers 的三个元素。只需使用 &lt;cfloop type="array"&gt; 替代 &lt;cfquery&gt; 即可。

英文:

As @EddieLotter pointed out, there are a number of ways to address this with Array functions alone. For example, here's ArrayFilter which has existed since ACF 10:

https://helpx.adobe.com/coldfusion/cfml-reference/coldfusion-functions/functions-a-b/arrayfilter.html

Code from their example:

  &lt;cfscript&gt;
        superheroes=[
              {&quot;name&quot;:&quot;Iron Man&quot;,&quot;member&quot;:&quot;Avengers&quot;},
              {&quot;name&quot;:&quot;Wonder Woman&quot;,&quot;member&quot;:&quot;Justice League&quot;},
              {&quot;name&quot;:&quot;Hulk&quot;,&quot;member&quot;:&quot;Avengers&quot;},
              {&quot;name&quot;:&quot;Thor&quot;,&quot;member&quot;:&quot;Avengers&quot;},
              {&quot;name&quot;:&quot;Aquaman&quot;,&quot;member&quot;:&quot;Justice League&quot;}
        ];
        avengers=ArrayFilter(superheroes,function(item){
              return item.member==&quot;Avengers&quot;;
        });
        writeDump(avengers);
  &lt;/cfscript&gt;

This outputs the three elements containing the key member with the value Avengers. Just use &lt;cfloop type=&quot;array&quot;&gt; instead of &lt;cfquery&gt;.

huangapple
  • 本文由 发表于 2023年7月13日 22:42:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/76680668.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定