【问题标题】:Stored Proc for xml path - order by not workingxml 路径的存储过程 - 按不工作排序
【发布时间】:2017-10-17 09:26:19
【问题描述】:

我正在尝试从具有可选 order by 的数据库中提取记录。为此,我创建了一个存储过程(为了便于阅读,省略了几列):

CREATE PROCEDURE [dbo].[sp_VendorOverview] (@sortCol nvarchar(50)=NULL)

AS

BEGIN

    SET NOCOUNT ON;
    select v.Vid, s.Salutation, v.LastName, CONVERT(varchar(100), CAST(v.VAT AS decimal(38,0))) AS VAT
    from vendors v
    inner join Salutations s
    on v.salutation=s.anrede

    order by
        CASE WHEN @sortCol='LastName' THEN v.LastName
            WHEN @sortCol='FirstName' THEN v.FirstName
            ELSE NULL
        END,
        CASE WHEN @sortCol ='VendorNumber' THEN v.VendorNumber
            ELSE v.Vid
        END
    for xml path('VendorBasic'), root('Vendors')
END

在 SSMS 中运行此 sp 时,一切正常,结果符合预期。 然而,当尝试像这样从 C# 应用程序中读取此内容时,情况并非如此:

var vendoren = new List<VendorBasic>();

using (var con = new SqlConnection(ConfigurationManager.ConnectionStrings["Vendor"].ConnectionString))
{
    var xml = string.Empty;
    con.Open();
    using (var cmd = new SqlCommand("dbo.sp_VendorOverview", con))
    {
        if (!string.IsNullOrEmpty(orderby))
            cmd.Parameters.AddWithValue("@sortCol", orderby);

        using (XmlReader idr = cmd.ExecuteXmlReader())
        {
            if (idr.Read())
            {
                xml = idr.ReadOuterXml();
            }
            idr.Close();
        }
        con.Close();
    }
    if (xml != string.Empty)
    {
        XmlRootAttribute xRoot = new XmlRootAttribute
        {
            ElementName = "Vendors",
            IsNullable = true
        };
        var engine = new XmlSerializer(typeof(List<VendorBasic>), xRoot);
        vendoren = (List<VendorBasic>)engine.Deserialize(new StringReader(xml));
    }
}

反序列化工作正常,为 VendorBasic 类设置了 XmlRoot 属性。 我确实得到了结果。 他们只是从来没有被 Vid 以外的任何人订购过。我设置了一个断点来检查参数是否正确应用,以防我想按任何其他列排序。它是:

我错过了什么吗?我是不是做错了什么?

【问题讨论】:

  • 为什么order by子句中有两个case表达式?单个 case 表达式应该就可以了....
  • @ZoharPeled 我需要两个,因为它们引用了两种不同的字段类型,nvarchar 和 int。 CASE WHEN 表达式尝试将字段类型统一为最高顺序之一,这意味着在这种情况下,如果我有例如,它将尝试将“LastName”转换为 int 类型。 VendorNumber 也在同一个 CASE 块中。必须先以艰难的方式学习。对于要处理的每种字段类型,您都需要一个 CASE 块。 :-)
  • 也许你应该这样做cmd.CommandType = CommandType.StoredProcedure;
  • @Evk 枪之子!!真的就是这样!让我震惊 - 请作为答案发布。 :-)

标签: c# sql-server stored-procedures sql-order-by for-xml-path


【解决方案1】:

你需要告诉SqlCommand你正在执行存储过程而不是任意命令,通过这样做

cmd.CommandType = CommandType.StoredProcedure;

如果没有它,它将基本上忽略您的所有参数并使用默认参数执行过程(在这种情况下为null)。您可能会在以下问题中找到更多信息:When executing a stored procedure, what is the benefit of using CommandType.StoredProcedure versus using CommandType.Text?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多