在工作中经常会碰到重复编程的情况。这些代码要么是完全重复的,要么是有规律的。但是手写起来都需要耗费时间,而且很容易出错。最近就碰到了几件,于是想到了利用CodeSmith来写模版生成,发现是一件很不错的事。
比如有这么一个需求,有很多表,每张表都有一张日志表,需要有这么个存储过程来更新日志表的数据。定义模版如下:
代码语言:javascript复制<%--
Author: LWQ
Description: 生成LOG表的存储过程
--%>
<%@ CodeTemplate Language="C#" TargetLanguage="T-SQL" Description="生成Insert存储过程." ResponseEncoding="UTF-8" %>
<%--加载使用访问数据库的组件SchemaExplorer,并声明其使用的命名空间。--%>
<%@ Assembly Name="SchemaExplorer" %>
<%@ Import Namespace="SchemaExplorer" %>
<%--定义一个存储表名称使用的变量,然后指明这个变量类型为数据库中的表--%>
<%@ Property Name="SourceTable" Type="SchemaExplorer.TableSchema" Category="Context" Description="要生成的表" %>
<%@ Property Name="LogTable" Type="SchemaExplorer.TableSchema" Category="Context" Description="日志表" %>
<%@ Property Name="DBName" Type="String" Category="New" Optional="True" Description="数据库名称" %>
<%@ Property Name="ProcName" Type="String" Category="New" Optional="True" Description="存储过程名称" %>
<%@ Import Namespace="System.Text.RegularExpressions" %>
<%
//设置存储过程名称
this.ProcName="dbo.Insert" SourceTable.Name "AndSetLog";
this.DBName = SourceTable.Database.Name;
%>
/*
* 利用CodeSmith生成。模板名:CreateLogStoredProcedure.cst。
* $Date: <%= DateTime.Now.ToShortDateString() %>
* $Author: <%= Environment.UserName %>
*
*/
GO
USE <%= DBName %>
GO
--如果存在,则删除
IF OBJECT_ID('<%= ProcName %>') IS NOT NULL
DROP PROCEDURE <%= ProcName %>
GO
CREATE PROCEDURE <%= ProcName %>
<%-- 设置参数--%>
<% int ignoreColumns=0; %>
<% for (int i = 0; i < SourceTable.Columns.Count; i ) { %>
<%if(!((bool)SourceTable.Columns[i].ExtendedProperties["CS_IsIdentity"].Value)
&& SourceTable.Columns[i].Name.ToLower()!="defaultflag") {%>
<%= GetSqlParameterStatement(SourceTable.Columns[i]) %>
<% if (i < SourceTable.Columns.Count - 1-ignoreColumns) { %>
,
<% } %>
<% }else{ignoreColumns ;}%>
<% } %>
<%-- 如果日志表存在ChangeType,则添加该参数--%>
<% if(LogTable.Columns.Contains("ChangeType")){ %>
<%= "," GetSqlParameterStatement(LogTable.Columns["ChangeType"]) %>
<% }%>
AS
BEGIN
SET NOCOUNT ON;
BEGIN TRANSACTION
DECLARE @errorSun INT
SET @errorSun=0
--更新<%=SourceTable.Name %>表状态为0
<%-- 如果原表存在DefaulFlag,则更新所有表的DefaulFlag状态为0--%>
<% if(SourceTable.Columns.Contains("DefaultFlag")){ %>
Update <%=SourceTable.Name %>
Set [DefaulFlag]=0
Where <%=SourceTable.Columns.Contains("ShopID")?"ShopID=@ShopID And ":string.Empty %><%=SourceTable.Columns.Contains("ObjectID")?"ObjectID=@ObjectID And ":string.Empty %>
<% }%>
SET @errorSun=@errorSun @@ERROR
--向<%=SourceTable.Name %>表插入数据,DefaultFlag设置为1
INSERT INTO [<%= SourceTable.Name %>]
(
<% for (int i = 0; i < SourceTable.Columns.Count; i ) { %>
<%-- 判断是否标识列,如果是,则不输出列名--%>
<%if(!((bool)SourceTable.Columns[i].ExtendedProperties["CS_IsIdentity"].Value)) {%>
[<%=SourceTable.Columns[i].Name %>]
<% if (i < SourceTable.Columns.Count - ignoreColumns) { %>,<% } %>
<% } %>
<% }%>
)
VALUES
(
<% for (int i = 0; i < SourceTable.Columns.Count; i ) { %>
<% if(SourceTable.Columns[i].Name.ToLower()=="defaultflag") { %>
<%= "1"%>
<% if (i < LogTable.Columns.Count - 1-ignoreColumns) { %>,<% } %>
<% continue; }%>
<%if(!((bool)SourceTable.Columns[i].ExtendedProperties["CS_IsIdentity"].Value)) {%>
<%= "@" SourceTable.Columns[i].Name%>
<% if (i < SourceTable.Columns.Count - 1-ignoreColumns) { %>,<% } %>
<% }%>
<% } %>
)
SET @errorSun=@errorSun @@ERROR
<% int ignoreColumnsForLog=0; %>
--向<%=LogTable.Name %>表插入数据,DefaultFlag设置为0
INSERT INTO [<%= LogTable.Name %>]
(
<% for (int i = 0; i < LogTable.Columns.Count; i ) { %>
<%-- 判断是否标识列,如果是,则不输出列名--%>
<%if(!((bool)LogTable.Columns[i].ExtendedProperties["CS_IsIdentity"].Value)) {%>
[<%=LogTable.Columns[i].Name %>]
<% if (i < LogTable.Columns.Count - 1 - ignoreColumnsForLog) { %>,<% } %>
<% }else {ignoreColumnsForLog ;} %>
<% }%>
)
VALUES
(
<% for (int i = 0; i < LogTable.Columns.Count; i ) { %>
<%if(!((bool)LogTable.Columns[i].ExtendedProperties["CS_IsIdentity"].Value)) {%>
<% if(LogTable.Columns[i].Name.ToLower()=="defaultflag") { %>
<%= "0"%>
<% if (i < LogTable.Columns.Count - 1-ignoreColumnsForLog) { %>,<% } %>
<% continue; }%>
<%= "@" LogTable.Columns[i].Name%>
<% if (i < LogTable.Columns.Count - 1-ignoreColumnsForLog) { %>,<% } %>
<% }%>
<% } %>
)
SET @errorSun=@errorSun @@ERROR
IF @errorSun<>0
BEGIN
ROLLBACK TRANSACTION
END
ELSE
BEGIN
COMMIT TRANSACTION
END
END
<script runat="template">
public string GetSqlParameterStatement(ColumnSchema column)
{
string param = "@" column.Name " " column.NativeType;
switch (column.DataType)
{
case DbType.Decimal:
{
param = "(" column.Precision ", " column.Scale ")";
break;
}
default:
{
if (column.Size > 0)
{
param = "(" column.Size ")";
}
break;
}
}
return param;
}
</script>