using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.Sql;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using System.Data.Common;
using System.Collections;
using Microsoft.SqlServer.Server;
namespace ClrDemoNet45
{
///
/// SQL Server 调用 CLR 示例程序集
/// 注意:1、方法必须是公共静态方法,
/// 2、返回值必须是 SqlInt32、System.Int32、System.Nullable 或 void
/// 3、加上SqlProcedure等特性
///
public class ClrDemo
{
#region 存储过程
///
/// 向调用客户端发送文本
///
[SqlProcedure]
public static void UseClr()
{
SqlContext.Pipe.Send("Hello,SQL Server CLR!");
}
///
/// 获取一个随机整数
/// 注意:方法的返回值,似乎不起使用
/// 返回值:方法一是使用输出参数 方法二是使用 SqlContext.Pipe.Send
///
[SqlProcedure]
public static int GetRandom()
{
Random random = new Random();
return random.Next(0, 1000);
}
///
/// 返回总数据行数
/// 使用 SqlContext.Pipe.ExecuteAndSend 直接发送 SqlCommand 结果到客户端(存储过程结果)
///
///
[SqlProcedure]
public static void ReturnCount()
{
using (SqlConnection conn = new SqlConnection("Context Connection=true"))
{
conn.Open();
string sqlText = "SELECT ISNULL(COUNT(*),0) AS StudentCount FROM dbo.Student;";
SqlCommand command = new SqlCommand(sqlText, conn);
command.CommandType = CommandType.Text;
SqlContext.Pipe.ExecuteAndSend(command);
conn.Close();
}
}
///
/// 获取总数据行数
/// 使用 out 参数,返回值。
///
[SqlProcedure]
public static int GetCount(out int totalCount)
{
using (SqlConnection conn = new SqlConnection("Context Connection=true"))
{
conn.Open();
string sqlText = "SELECT ISNULL(COUNT(*),0) AS StudentCount FROM dbo.Student;";
SqlCommand command = new SqlCommand(sqlText, conn);
command.CommandType = CommandType.Text;
totalCount = (int)command.ExecuteScalar();
conn.Close();
return totalCount;
}
}
///
/// 查询数据表
/// SqlContext.Pipe.ExecuteAndSend 发送DataTable
///
[SqlProcedure]
public static void GetStudents()
{
using (SqlConnection conn = new SqlConnection("Context Connection=true"))
{
conn.Open();
string sqlText = "SELECT * FROM dbo.Student;";
SqlCommand command = new SqlCommand(sqlText, conn);
command.CommandType = CommandType.Text;
SqlContext.Pipe.ExecuteAndSend(command);
conn.Close();
}
}
///
/// 使用 SqlDataRecord 发送单行数据
///
[SqlProcedure]
public static void UseSqlDataRecord()
{
//创建 metadata 作为 SqlDataRecord 列
List columns = new List()
{
new SqlMetaData("Id", SqlDbType.Int),
new SqlMetaData("SchoolName", SqlDbType.NVarChar, 50),
new SqlMetaData("ClassNumber", SqlDbType.Int),
new SqlMetaData("StudentNumber", SqlDbType.Int)
};
SqlDataRecord record = new SqlDataRecord(columns.ToArray());
// 设置列的值
record.SetInt32(0, -1);
record.SetString(1, "太康七高");
record.SetInt32(2, 20);
record.SetInt32(3, 55);
// 发送到客户端
SqlContext.Pipe.Send(record);
}
///
/// 返回自定义结果集
/// 使用 SendResultsStart SendResultsRow SendResultsEnd
///
[SqlProcedure]
public static void UseSendResultsRow()
{
//创建 metadata 作为 SqlDataRecord 列
List columns = new List()
{
new SqlMetaData("Id", SqlDbType.Int),
new SqlMetaData("SchoolName", SqlDbType.NVarChar, 50),
new SqlMetaData("ClassNumber", SqlDbType.Int),
new SqlMetaData("StudentNumber", SqlDbType.Int)
};
SqlDataRecord record = new SqlDataRecord(columns.ToArray());
//开始发送
SqlContext.Pipe.SendResultsStart(record);
// 发送10行数据到客户端
for (int i = 1; i <= 10; i++)
{
// 设置列的值
record.SetInt32(0, i);
record.SetString(1, $"太康{i}高");
record.SetInt32(2, 20 + i);
record.SetInt32(3, 100 + i);
// 发送当前行到客户端
SqlContext.Pipe.SendResultsRow(record);
}
// 发送结束
SqlContext.Pipe.SendResultsEnd();
}
///
/// 汇总学校学生数量
///
[SqlProcedure]
public static void SummaryData()
{
using (SqlConnection conn = new SqlConnection("Context Connection=true"))
{
conn.Open();
string sqlText = "UPDATE dbo.School SET StudentNumber=(SELECT COUNT(*) FROM dbo.Student WHERE SchoolId = School.Id);";
SqlCommand command = new SqlCommand(sqlText, conn);
command.CommandType = CommandType.Text;
SqlContext.Pipe.ExecuteAndSend(command);
conn.Close();
}
}
///
/// 汇总学生数量
/// (只为演示效果,实际开发一条语句即可)
///
[SqlProcedure]
public static void SummaryStudentCount()
{
bool isSucess = true;
string message = "ok";
try
{
using (SqlConnection conn = new SqlConnection("Context Connection=true"))
{
conn.Open();
//1、拉所有学校
SqlDataAdapter da = new SqlDataAdapter("SELECT Id FROM dbo.School;", conn);
DataTable schoolTable = new DataTable();
da.Fill(schoolTable);
foreach (DataRow row in schoolTable.Rows)
{
var schoolId = (int)row["Id"];
var studentCount = 0;
using (SqlCommand queryStudentCountCommand = new SqlCommand())
{
//查询该学校学生人数
string queryStudentCountText = "SELECT ISNULL(COUNT(*),0) AS StudentCount FROM dbo.Student where [SchoolId]=@SchoolId;";
SqlParameter schoolIdPara = new SqlParameter()
{
ParameterName = "@SchoolId",
Direction = ParameterDirection.Input,
SqlDbType = SqlDbType.Int,
Value = schoolId,
};
queryStudentCountCommand.Connection = conn;
queryStudentCountCommand.CommandText = queryStudentCountText;
queryStudentCountCommand.CommandType = CommandType.Text;
queryStudentCountCommand.Parameters.Add(schoolIdPara);
studentCount = (int)queryStudentCountCommand.ExecuteScalar();
}
//更新
using (SqlCommand updateStudentCountCommand = new SqlCommand())
{
string updateStudentCountText = "UPDATE dbo.School SET StudentNumber=@StudentNumber WHERE Id=@SchoolId;";
SqlParameter updateSchoolIdPara = new SqlParameter()
{
ParameterName = "@SchoolId",
Direction = ParameterDirection.Input,
SqlDbType = SqlDbType.Int,
Value = schoolId,
};
SqlParameter updateStudentCountPara = new SqlParameter()
{
ParameterName = "@StudentNumber",
Direction = ParameterDirection.Input,
SqlDbType = SqlDbType.Int,
Value = studentCount,
};
updateStudentCountCommand.Connection = conn;
updateStudentCountCommand.CommandText = updateStudentCountText;
updateStudentCountCommand.CommandType = CommandType.Text;
updateStudentCountCommand.Parameters.Add(updateSchoolIdPara);
updateStudentCountCommand.Parameters.Add(updateStudentCountPara);
updateStudentCountCommand.ExecuteNonQuery();
}
}
conn.Close();
}
}
catch (Exception ex)
{
isSucess = false;
message = ex.Message;
}
List columns = new List()
{
new SqlMetaData("Sucess", SqlDbType.Bit),
new SqlMetaData("Message", SqlDbType.NVarChar, 500),
};
SqlDataRecord record = new SqlDataRecord(columns.ToArray());
record.SetBoolean(0, isSucess);
record.SetString(1, message);
SqlContext.Pipe.Send(record);
}
#endregion
#region 自定义函数
///
/// 标量函数
/// 查询指定学校的学生数量
///
[SqlFunction(DataAccess = DataAccessKind.Read, IsDeterministic = false)]
public static int QuerySchoolStudentCount(int schoolId)
{
using (SqlConnection conn = new SqlConnection("Context Connection=true"))
{
conn.Open();
string sqlText = "SELECT ISNULL(COUNT(*),0) AS StudentCount FROM dbo.Student where [SchoolId]=@SchoolId;";
SqlParameter schoolIdPara = new SqlParameter()
{
ParameterName = "@SchoolId",
Direction = ParameterDirection.Input,
SqlDbType = SqlDbType.Int,
Value = schoolId,
};
SqlCommand command = new SqlCommand()
{
Connection = conn,
CommandText = sqlText,
CommandType = CommandType.Text,
};
command.Parameters.Add(schoolIdPara);
var studentCount = (int)command.ExecuteScalar();
conn.Close();
return studentCount;
}
}
///
/// 表值函数:返回一个数据集合,必须用一个填充数据的方法,在属性中用FillRowMethodName来表示,且返回值应该为IEnumerable类型
/// 查询指定学校的所有学生
///
[SqlFunction(DataAccess = DataAccessKind.Read, FillRowMethodName = "FillRow_ReturnData", IsDeterministic = false)]
public static IEnumerable QueryStudent()
{
IList returnDataList = new List();
returnDataList.Add(new School() { Id = 1, SchoolName = "太康一高", ClassNumber = 10, StudentNumber = 150 });
returnDataList.Add(new School() { Id = 2, SchoolName = "太康二高", ClassNumber = 20, StudentNumber = 250 });
returnDataList.Add(new School() { Id = 3, SchoolName = "太康三高", ClassNumber = 30, StudentNumber = 350 });
return returnDataList;
}
///
/// 填充方法
///
///
///
///
public static void FillRow_ReturnData(object returnDataObj, out SqlInt32 Id, out SqlString SchoolName, out SqlInt32 ClassNumber, out SqlInt32 StudentNumber)
{
School school = returnDataObj as School;
Id = school.Id;
SchoolName = school.SchoolName;
ClassNumber = school.ClassNumber;
StudentNumber = school.StudentNumber;
}
///
/// 聚合函数
/// 查询指定学校的所有学生
///
[SqlFunction]
public static void QuaryAvgStudent(int schoolId)
{
using (SqlConnection conn = new SqlConnection("Context Connection=true"))
{
conn.Open();
string sqlText = "SELECT ISNULL(COUNT(*),0) AS StudentCount FROM dbo.Student where [SchoolId]=@SchoolId;";
SqlParameter schoolIdPara = new SqlParameter()
{
ParameterName = "@SchoolId",
Direction = ParameterDirection.Input,
SqlDbType = SqlDbType.Int,
Value = schoolId,
};
SqlCommand command = new SqlCommand()
{
Connection = conn,
CommandText = sqlText,
CommandType = CommandType.Text,
};
command.Parameters.Add(schoolIdPara);
SqlContext.Pipe.ExecuteAndSend(command);
conn.Close();
}
}
#endregion
}
}