首页 > 解决方案 > SqlQuerySpec 参数化查询不返回结果

问题描述

我不确定这是否是模拟器问题,但我有一个非常简单的查询

 var collectionUri = UriFactory.CreateDocumentCollectionUri(Constants.CosmosDbName, CollectionName);
            var spec = new SqlQuerySpec()
            {
                QueryText = "SELECT * FROM Users u WHERE u.firstName = @firstname",
                Parameters = new SqlParameterCollection
                {
                    new SqlParameter{
                        Name = "@firstname",
                        Value = value
                    }
                }
            };

            var query = client.CreateDocumentQuery<User>(collectionUri, spec);
            var users = await query.ToListAsync();  

参数化查询不返回结果,即 0 个用户,而下面的相同普通查询返回 1 个匹配 WHERE 条件的用户:

            spec.Parameters.Clear();
            spec.QueryText = $"SELECT * FROM Users u WHERE u.firstName = '{value}'";
            query = client.CreateDocumentQuery<User>(collectionUri, spec);
            users = await query.ToListAsync();    // returns 1 user

我是否需要以某种方式显式启用参数化查询,或者我在上面的参数化查询中做错了什么?

标签: azure-cosmosdbsql-parametrized-query

解决方案


问题是一种 var 陷阱

SqlParameter 值取自 Azure 函数 HttpRequest 请求:

var value = req.Query["firstname"]; 

这是

Microsoft.Extensions.Primitives.StringValues value = req.Query["firstname"];

当使用 StringValues 类型的值创建 SqlParameter 时,它会进行稍微不同的查询:

SELECT * FROM Users u WHERE u.firstName = ['Dima']

这里的括号 ['Dima'] 是多余的

正确的查询必须不带括号

SELECT * FROM Users u WHERE u.firstName = 'Dima'

所以要修复参数化查询,参数值应该是一个字符串

new SqlParameter("@firstname",value.ToString())

推荐阅读