CodeSmith系列(一)——使用CodeSmith生成存储过程

在工作中经常会碰到重复编程的情况。这些代码要么是完全重复的,要么是有规律的。但是手写起来都需要耗费时间,而且很容易出错。最近就碰到了几件,于是想到了利用CodeSmith来写模版生成,发现是一件很不错的事。

比如有这么一个需求,有很多表,每张表都有一张日志表,需要有这么个存储过程来更新日志表的数据。定义模版如下:

<%--
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>
时间: 2024-07-31 01:47:35

CodeSmith系列(一)——使用CodeSmith生成存储过程的相关文章

有没有自动生成存储过程的工具?

问题描述 谢谢高手啊,我想下载一个那样的工具了!! 解决方案 解决方案二:好像没有啊!自己写吧解决方案三:有..你去搜一下李天平的动软.net代码生成器,,里面有生成存储过程的..解决方案四:哦,谢谢高手啦

实用的银行转账存储过程和流水号生成存储过程_MsSql

银行转账存储过程 USE [BankInfor] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ALTER PROCEDURE [dbo].[Transfer](@inAccount int,@outAccount int,@amount float) as declare @totalDeposit float; begin select @totalDeposit=total from Account where AccountNum

实用的银行转账存储过程和流水号生成存储过程

银行转账存储过程 USE [BankInfor] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ALTER PROCEDURE [dbo].[Transfer](@inAccount int,@outAccount int,@amount float) as declare @totalDeposit float; begin select @totalDeposit=total from Account where AccountNum

CodeSmith系列(二)——使用CodeSmith生成ASP.NET后台代码

因为表单的后台代码都差不多,所以采用了CodeSmith生成.由于表单的控制是基于XML的,所以可以根据XML自定义生成.由于没时间,就不多写了,具体模板代码见最后. 在这里,先选择变量.如下: XMl文件内容如下: <?xml version="1.0" encoding="utf-8" ?> <FieldConfig> <GlobalDefaultConfig> <Description>付款确认单</Des

CodeSmith系列(三)——使用CodeSmith生成ASP.NET页面

  仍然使用之前的XML文件,然后设置生成参数如下: 生成调整后的页面如下: 生成的代码如下: <%@ Control Language="C#" AutoEventWireup="true" CodeBehind="ConfirmationForPayment.ascx.cs" Inherits="NBShop.UserControls.Form.ConfirmationForPayment" EnableViewSt

【天池直播】同济梁教授运筹学系列直播三--列生成2:万变不离其宗,强大的并行机排程!

鸠摩智靠着小无相功的内功,用少林72绝学打败了少林寺的大和尚,并行机排程,即列生成中的小无相功. 本次直播,我们且看并行机在人员排班,医疗卫生,车辆运输,航空排程,生产运作等方面的应用. 对并行机排程想要了解以及有任何疑问的同学,请在技术圈帖子留言,梁教授会统一解答哦~ 直播主题:列生成2--万变不离其宗,强大的并行机排程! 直播时间:11月9日 20:00 直播链接:点击查看 直播嘉宾: 梁哲 天池昵称梁哲 同济大学同济大学管理科学与工程教授博导,天池航空AI大赛冠军团队"同济经管组合优化&q

超级简单:共享两个自动生成存储过程的工具

开发一个项目或者开发一个应用系统初期大多数都是从数据库,类,UI界面 开始的.其中最令人厌烦的是写些简单的CRUD的存储过程,以及调用这些存储过 程的方法的类. 我花了很多时间在网上寻找,去找一个能根据能数据库中一个存在的数据表 ,为我们产生大部分存储过程和调用这些存储过程C#代码的实用的程序.这里共 享两个我觉得还不错的程序给大家. 第一个是SQLAutoGen,如下图:

MySQL实战系列3:视图、存储过程、函数、索引全解析

作者介绍 索宁,擅长Python开发.MySQL.前端等众多技术领域,曾负责众多企业安全架构解决方案 ,涉猎行业有媒体.出版社.航空运输.医疗.军队.政府.教育等.   一.视图   视图是查询命令结果构成的一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集合,并可以当作表来查询使用.   1创建视图  --格式:CREATE VIEW 视图名称 AS  SQL语句 CREATE VIEW v1 AS SELET nid,

小系统单据自动生成存储过程_MsSql

复制代码 代码如下: create table [order] ( code varchar(50), createtime datetime ) --应用 usp_ordernumbergenerate(@prefix = 'PRC100701') --传入前缀 大类+单据编码+6位日期 --获取当日该类单据最大流水号(需按日归零) --此处判断有两种方法:一种是根据传入6位日期判断:另一种根据单据创建日期字段(前提:表有创建时间字段) create procedure usp_OrderNu