代码之家  ›  专栏  ›  技术社区  ›  Phil

SQL Server CLR存储过程json参数

  •  1
  • Phil  · 技术社区  · 17 年前

    我遇到了一个场景,我想将大量数据传递给存储过程以生成一些动态SQL。

    我要传递的数据存储在这个json/c类对象中,我在ASP.NET MVC Web项目中使用该对象。

    [
     {
      "code":"ABC123",
      "Count": "12998",
      "Params":
      [
        {"name": "Recent", "value": "0-12m"},
        {"name": "Orders", "value": "1"}
      ]
     },
     {
      "code":"ABC124",
      "Count": "13998",
      "Params":
      [
       {"name": "Recent", "value": "0-12m"},
       {"name": "Orders", "value": "2"}
      ]
     },
     {
      "code":"ABC125",
      "Count": "7998",
      "Params":
      [
       {"name": "Recent", "value": "0-12m"},
       {"name": "Orders", "value": "3"}
      ]
     }
    ]
    .....
    

    然后使用这个文本参数转换回一个JSON对象,我在一个动作过滤器中使用这个参数将它转换成一个对象。

    public class ObjectFilter : ActionFilterAttribute
    {
    
        public string Param { get; set; }
    
        public Type RootType { get; set; }
    
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
    
            if ((filterContext.HttpContext.Request.ContentType ?? string.Empty).Contains("application/json"))
            {
    
                object o =
    
                new DataContractJsonSerializer(RootType).ReadObject(filterContext.HttpContext.Request.InputStream);
                filterContext.HttpContext.Request.InputStream.Seek(0, SeekOrigin.Begin); // Rewind InputStream for other filters
    
                filterContext.ActionParameters[Param] = o;
    
            }
    
            else
            {
    
                var xmlRoot = XElement.Load(new StreamReader(filterContext.HttpContext.Request.InputStream,
    
                filterContext.HttpContext.Request.ContentEncoding));
    
                object o = new XmlSerializer(RootType).Deserialize(xmlRoot.CreateReader());
    
                filterContext.ActionParameters[Param] = o;
    
            }
    
        }
    

    }

    然后在clr存储过程中使用c等创建SQL语句,如:

    UPDATE [Sample]
    SET [Field] =
    CASE
    WHEN [Recent] = "0-12m" AND [Orders] = "1" THEN "ABC123"
    WHEN [Recent] = "0-12m" AND [Orders] = "2" THEN "ABC124"
    WHEN [Recent] = "0-12m" AND [Orders] = "3" THEN "ABC125"
    ...
    

    这有可能吗?有人做过这样的事吗?我看到过一些关于使用XML参数的文章,但是没有一篇使用varchar参数的文章使用反序列化(?)杰森。

    3 回复  |  直到 15 年前
        1
  •  1
  •   Mitch Wheat    17 年前

    有可能;请参阅动态SQL上的规范引用: The Curse and Blessings of Dynamic SQL

        2
  •  1
  •   Phil    17 年前

    我试图使用我的代码来解析一个JSON字符串参数,但是所需的名称空间在SQL CLR项目中不可用,因此我已经切换到文档化的XML参数。

        3
  •  1
  •   Teraberry    15 年前

    如果您自己正在构建不安全的程序集,则只能使用不安全的程序集,如DataContractJSonserializer。另一种选择是跳过对不安全程序集的引用和使用,编写自己的JSON解析代码(或者从其他人那里复制它)。

    推荐文章