PCB MS SQL 标量函数(CLR) 实现转Json方法
Posted pcbren
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PCB MS SQL 标量函数(CLR) 实现转Json方法相关的知识,希望对你有一定的参考价值。
一.准备需转为json字符串的DataTable数据
在数据库中执行一段SQL返回的数据
需转换后的JSON字符串的效果
[{"TechName":"开料","ItemName":"综合利用率是否为最高","ItemPara":"/"},{"TechName":"开料","ItemName":"综合利用率","ItemPara":"68.36"},{"TechName":"开料","ItemName":"纬向余料","ItemPara":"0"},{"TechName":"开料","ItemName":"经向余料","ItemPara":"0"},{"TechName":"开料","ItemName":"是否为小交货面积拼板","ItemPara":"n"},{"TechName":"开料","ItemName":"纬向尺寸","ItemPara":"24"},{"TechName":"开料","ItemName":"是否为阴阳铜结构","ItemPara":"N"},{"TechName":"开料","ItemName":"是否横竖开料","ItemPara":"N"},{"TechName":"开料","ItemName":"生产尺寸长","ItemPara":"24"},{"TechName":"开料","ItemName":"生产尺寸宽","ItemPara":"18"},{"TechName":"开料","ItemName":"拼板利用率","ItemPara":"68.36"},{"TechName":"开料","ItemName":"开料图纸","ItemPara":"/"},{"TechName":"开料","ItemName":"是否顾客指定板材","ItemPara":"N"},{"TechName":"开料","ItemName":"开料数","ItemPara":"4"},{"TechName":"开料","ItemName":"大料经向尺寸","ItemPara":"36"},{"TechName":"开料","ItemName":"大料纬向尺寸","ItemPara":"48"},{"TechName":"开料","ItemName":"成品尺寸长","ItemPara":"12"},{"TechName":"开料","ItemName":"成品尺寸宽","ItemPara":"13.5"},{"TechName":"开料","ItemName":"是否为PTFE板材","ItemPara":"N"},{"TechName":"开料","ItemName":"交货拼板个数","ItemPara":"1"},{"TechName":"开料","ItemName":"生产拼板个数","ItemPara":"1176"},{"TechName":"开料","ItemName":"交货单位","ItemPara":"U"},{"TechName":"开料","ItemName":"是否为凹蚀板材","ItemPara":"N"}]
二.C#写SQL SERVER(CLR)转JSON函数
先执行SQL返回DataTable,接着再将DataTable转为Json, 这里转为Json有2种方法,代码都贴在下方了
/// <summary> /// 执行SQL语句 返回的DataTable 转为 Json /// </summary> /// <param name="StrSQL"></param> /// <returns></returns> [Microsoft.SqlServer.Server.SqlFunction(DataAccess = DataAccessKind.Read)] public static string ExecSQL2Json(string StrSQL) { DataTable dt = getDataTable(StrSQL); //return DataTable2Json(dt); //方法1 转为 Json if (dt is null) return null; List<Dictionary<string, object>> list = new List<Dictionary<string, object>>(); foreach (DataRow dr in dt.Rows) { Dictionary<string, object> result = new Dictionary<string, object>(); foreach (DataColumn dc in dt.Columns) { result.Add(dc.ColumnName, dr[dc].ToString()); } list.Add(result); } return Json.Serialize(list);//方法2 转为 Json } /// <summary> /// 执行SQL获取DataTable /// </summary> /// <param name="StrSQL"></param> /// <returns></returns> private static DataTable getDataTable(string StrSQL) { DataTable dt = new DataTable(); try { using (SqlConnection cn = new SqlConnection("context connection=true")) { using (SqlDataAdapter da = new SqlDataAdapter(StrSQL, cn)) { DataSet ds = new DataSet(); da.Fill(ds, "tab"); dt = ds.Tables["tab"]; } } } catch (Exception ex) { throw; } return dt; }
方法一:DataTable转Json
/// <summary> /// DataTable转Json /// </summary> /// <param name="table"></param> /// <returns></returns> public static string DataTable2Json(DataTable table) { var JsonString = new StringBuilder(); if (table.Rows.Count > 0) { JsonString.Append("["); for (int i = 0; i < table.Rows.Count; i++) { JsonString.Append("{"); for (int j = 0; j < table.Columns.Count; j++) { object ValueNull = table.Rows[i][j]; if (ValueNull == DBNull.Value) { JsonString.Append("\\"" + table.Columns[j].ColumnName.ToString() + "\\":null" + ((j < table.Columns.Count - 1) ? "," : "")); } else { string Value = table.Rows[i][j].ToString(); if (table.Columns[j].DataType == typeof(string) || table.Columns[j].DataType == typeof(DateTime) || table.Columns[j].DataType == typeof(Guid)) { JsonString.Append("\\"" + table.Columns[j].ColumnName.ToString() + "\\":" + "\\"" + Value + "\\"" + ((j < table.Columns.Count - 1) ? "," : "")); } else { if (table.Columns[j].DataType == typeof(bool)) Value = Value.ToLower(); JsonString.Append("\\"" + table.Columns[j].ColumnName.ToString() + "\\":" + Value + ((j < table.Columns.Count - 1) ? "," : "")); } } } JsonString.Append("}" + ((i < table.Rows.Count - 1) ? "," : "")); } JsonString.Append("]"); } return JsonString.ToString(); }
方法二: 开源MiniJSON类解析Json字符串
using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; namespace SQLClr { /// <summary> /// This class encodes and decodes JSON strings. /// Spec. details, see http://www.json.org/ /// /// JSON uses Arrays and Objects. These correspond here to the datatypes IList and IDictionary. /// All numbers are parsed to doubles. /// </summary> public static class Json { /// <summary> /// Parses the string json into a value /// </summary> /// <param name="json">A JSON string.</param> /// <returns>An List<object>, a Dictionary<string, object>, a double, an integer,a string, null, true, or false</returns> //反序列化 public static object Deserialize(string json) { // save the string for debug information if (json == null) { return null; } return Parser.Parse(json); } //阻止其他类从该类继承 sealed class Parser : IDisposable { const string WORD_BREAK = "{}[],:\\""; public static bool IsWordBreak(char c) { // 如果 c 是空白,则为 true;否则,为 false;报告指定 Unicode 字符在此字符串中的第一个匹配项的索引。 return Char.IsWhiteSpace(c) || WORD_BREAK.IndexOf(c) != -1; } enum TOKEN { NONE, CURLY_OPEN, CURLY_CLOSE, SQUARED_OPEN, SQUARED_CLOSE, COLON, COMMA, STRING, NUMBER, TRUE, FALSE, NULL }; // 实现从字符串进行读取的 System.IO.TextReader。 StringReader json; Parser(string jsonString) { json = new StringReader(jsonString); } public static object Parse(string jsonString) { using (var instance = new Parser(jsonString)) { return instance.ParseValue(); } } //释放 public void Dispose() { json.Dispose(); json = null; } Dictionary<string, object> ParseObject() { Dictionary<string, object> table = new Dictionary<string, object>(); // ditch opening brace json.Read(); // { while (true) { switch (NextToken) { case TOKEN.NONE: return null; case TOKEN.COMMA: continue; case TOKEN.CURLY_CLOSE: return table; default: // name string name = ParseString(); if (name == null) { return null; } // : if (NextToken != TOKEN.COLON) { return null; } // ditch the colon json.Read(); // value table[name] = ParseValue(); break; } } } List<object> ParseArray() { List<object> array = new List<object>(); // ditch opening bracket json.Read(); // [ bool parsing = true; while (parsing) { TOKEN nextToken = NextToken; switch (nextToken) { case TOKEN.NONE: return null; case TOKEN.COMMA: continue; case TOKEN.SQUARED_CLOSE: parsing = false; break; default: object value = ParseByToken(nextToken); array.Add(value); break; } } return array; } object ParseValue() { TOKEN nextToken = NextToken; return ParseByToken(nextToken); } object ParseByToken(TOKEN token) { switch (token) { case TOKEN.STRING: return ParseString(); case TOKEN.NUMBER: return ParseNumber(); case TOKEN.CURLY_OPEN: return ParseObject(); case TOKEN.SQUARED_OPEN: return ParseArray(); case TOKEN.TRUE: return true; case TOKEN.FALSE: return false; case TOKEN.NULL: return null; default: return null; } } string ParseString() { StringBuilder s = new StringBuilder(); char c; // ditch opening quote json.Read(); bool parsing = true; while (parsing) { if (json.Peek() == -1) { parsing = false; break; } c = NextChar; switch (c) { case \'"\': parsing = false; break; case \'\\\\\': if (json.Peek() == -1) { parsing = false; break; } c = NextChar; switch (c) { case \'"\': case \'\\\\\': case \'/\': s.Append(c); break; case \'b\': s.Append(\'\\b\'); break; case \'f\': s.Append(\'\\f\'); break; case \'n\': s.Append(\'\\n\'); break; case \'r\': s.Append(\'\\r\'); break; case \'t\': s.Append(\'\\t\'); break; case \'u\': var hex = new char[4]; for (int i = 0; i < 4; i++) { hex[i] = NextChar; } s.Append((char)Convert.ToInt32(new string(hex), 16)); break; } break; default: s.Append(c); break; } } return s.ToString(); } object ParseNumber() { string number = NextWord; // 摘要: // 报告指定 Unicode 字符在此字符串中的第一个匹配项的索引。 // // 参数: // value: // 要查找的 Unicode 字符。 // // 返回结果: // 如果找到该字符,则为 value 的从零开始的索引位置;如果未找到,则为 -1。 if (number.IndexOf(\'.\') == -1) { long parsedInt; // 将数字的字符串表示形式转换为它的等效 64 位有符号整数。一个指示转换是否成功的返回值。 Int64.TryParse(number, out parsedInt); return parsedInt; } double parsedDouble; Double.TryParse(number, out parsedDouble); return parsedDouble; } // void EatWhitespace() { //指示指定字符串中位于指定位置处的字符是否属于空白类别。 while (Char.IsWhiteSpace(PeekChar)) { json.Read(); //摘要: // 返回下一个可用的字符,但不使用它。 // // 返回结果: // 表示下一个要读取的字符的整数,或者,如果没有更多的可用字符或该流不支持查找,则为 -1。 if (json.Peek() == -1) { break; } } } char PeekChar { get { // 读取输入字符串中的下一个字符并将该字符的位置提升一个字符。 // // 返回结果: // 基础字符串中的下一个字符,或者如果没有更多的可用字符,则为 -1。 return Convert.ToChar(json.Peek()); } } char NextChar { get { return Convert.ToChar(json.Read()); } } string NextWord { get { // 表示可变字符字符串。无法继承此类。 StringBuilder word = new StringBuilder(); while (!IsWordBreak(PeekChar)) { // 摘要: // 在此实例的结尾追加指定 Unicode 字符的字符串表示形式。 // // 参数: // value: // 要追加的 Unicode 字符。 // // 返回结果: // 完成追加操作后对此实例的引用。 word.Append(NextChar); //下一个字符为空 if (json.Peek() == -1) { break; } } // return word.ToString(); } } TOKEN NextToken { get { EatWhitespace(); if (json.Peek() == -1) { return TOKEN.NONE; } switch (PeekChar) { case \'{\': return TOKEN.CURLY_OPEN; case \'}\': json.Read(); return TOKEN.CURLY_CLOSE; case \'[\': return TOKEN.SQUARED_OPEN; case \']\': json.Read(); return TOKEN.SQUARED_CLOSE; case \',\': json.Read(); return TOKEN.COMMA; case \'"\': return TOKEN.STRING; case \':\': return TOKEN.COLON; case \'0\': case \'1\': case \'2\': case \'3\': case \'4\': case \'5\': case \'6\': case \'7\': case \'8\': case \'9\': case \'-\': return TOKEN.NUMBER; } switch (NextWord) { case "false": return TOKEN.FALSE; case "true": return TOKEN.TRUE; case "null": return TOKEN.NULL; } return TOKEN.NONE; } } } /// <summary> /// Converts a IDictionary / IList object or a simple type (string, int, etc.) into a JSON string /// </summary> /// <param name="json">A Dictionary<string, object> / List<object></param> /// <returns>A JSON encoded string, or null if object \'json\' is not serializable</returns> public static string Serialize(object obj) { return Serializer.Serialize(obj); } sealed class Serializer { StringBuilder builder; Serializer() { //创建生成器 builder = new StringBuilder(); } //序列化 public static PCB MS SQL表值函数与CLR 表值函数 (例:字符串分割转表)PCB MS SQL CLR聚合函数(函数作用,调用顺序,调用次数) CLR说明