版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Asa_Jim/article/details/47048775
整个2014年我大概都在搞一件事情--写报表的存储过程,在开始的时候经常会碰到sql 脚本整理出了问题导致的升级错误,后面我自己总结了一套sql 脚本维护和升级的方法,还算有效吧,最近整理出来方便有这方面需要的朋友看看,改改,用用。
先看看我过去这一年的sql 脚本吧,为了不泄露某些信息,特用程序猿利器(一)中的程序批量将 脚本文件名做了替换。
我的心得:
- 做好分类是必要的,例如根据公司,报表用途,建立合适的分类文件夹和前缀后缀
- 必须确保你本地整理的sql 脚本是最新的,每次修改最好从本地的脚本改起,然后你根据修改时间就可以判断出哪些是下次要升级的脚本
- 大的改动之前先备份相应的脚本
- sql 脚本以方便升级形成一个完整的开发模板,这样自动合并后不需要修改就能直接执行
我的sql 脚本大概结构如下,先判断这个存储过程是否存在,有则删除,然后创建,这样可以保证能升级到。然后写好步骤去实现报表
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[usp_Rpt_e14e591fcb514834861c5a69810f8f3e]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[usp_Rpt_e14e591fcb514834861c5a69810f8f3e]
GO
CREATE PROCEDURE usp_Rpt_e14e591fcb514834861c5a69810f8f3e
@JMSCustID uniqueidentifier='00000000-0000-0000-0000-000000000000', --加盟商系统有该参数
@ShopID bigint=0, --加盟商系统有该参数
@Year Int,
@Month Int,
@StockWhere nvarchar(500),
@WareHouseWhere nvarchar(500)
AS
BEGIN
DECLARE @SQLString nvarchar(4000); --动态sql字串
--1 条件表
--1.1 产生查询起止日期
...............
--1.3
...............
--1.5 Create table #Temp
..........
--2 数据处理
--2.1 期初数据处理
..................
--3 select All
select * from #Temp
Drop table #Temp
END
GO
sql 脚本编辑完成后保存到相应的文件夹下面,然后你根据修改时间排序就可以获得最近有修改过的脚本了,拷贝出来,放到合并用的文件夹下面,然后重点来了,用自动合并小工具实现脚本合并成一个升级脚本。
基本代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace MakeUpdateScript
{
class Program
{
static void Main(string[] args)
{
string upDateDirectoryName = "Update";
string baseFilePaht = @"K:\";//Environment.CurrentDirectory;
if (baseFilePaht == string.Empty)
{
Console.WriteLine("K盘不存在!");
Console.ReadKey();
return;
}
//exists the Directory, if not then create
string directoryFullPaht = baseFilePaht + @"\" + upDateDirectoryName;
if (Directory.Exists(upDateDirectoryName) == false)
{
Directory.CreateDirectory(directoryFullPaht);
}
string[] sqlFilesArray = GetFiles(baseFilePaht);
if (sqlFilesArray == null || sqlFilesArray.Length == 0)
{
Console.WriteLine("无法获取到升级的脚本或文件夹!");
Console.ReadKey();
return;
}
int index =0;
string updateFileName = directoryFullPaht + @"\";
string newFileName = string.Empty;
string content = string.Empty;
StringBuilder saveStr = new StringBuilder();
foreach (var item in sqlFilesArray)
{
if (index % 10 == 0)
{
newFileName= updateFileName + (index / 10).ToString() + ".sql";
}
content = "--" + item.Replace(baseFilePaht + @"\", "").Split('.')[0] + " " + DateTime.Now.ToShortDateString() +" "+ DateTime.Now.ToShortTimeString() + Environment.NewLine;
using (FileStream fs = File.OpenRead(item))
{
System.Text.Encoding encode = GetType(fs);
content += File.ReadAllText(item, encode) +Environment.NewLine;
}
saveStr.Append(content);
File.Delete(item);
if (index % 10 == 9 || index == sqlFilesArray.Length - 1)
{
File.WriteAllText(newFileName, saveStr.ToString(), Encoding.Default);
saveStr.Clear();
}
index++;
}
Console.WriteLine("脚本已经生成!");
Console.ReadKey();
}
public static string[] GetFiles(string directoryPaht)
{
string[] fileNames = Directory.GetFiles(directoryPaht + @"\","*.sql"); //获取该文件夹下面的所有文件名
return fileNames;
}
/// <summary>
/// Get Files Encoding
/// </summary>
/// <param name="fs"></param>
/// <returns></returns>
public static System.Text.Encoding GetType(FileStream fs)
{
BinaryReader r =new BinaryReader(fs,System.Text.Encoding.Default);
byte[] ss = r.ReadBytes(4);
//编码类型 Coding=编码类型.ASCII;
if (ss[0] <=0xEF)
{
if (ss[0] ==0xEF&& ss[1] ==0xBB&& ss[2] ==0xBF)
{
return System.Text.Encoding.UTF8;
}
else
if (ss[0] ==0xFE&& ss[1] ==0xFF)
{
return System.Text.Encoding.BigEndianUnicode;
}
else
if (ss[0] ==0xFF&& ss[1] ==0xFE)
{
return System.Text.Encoding.Unicode;
}
else
{
return System.Text.Encoding.Default;
}
}
else
{
return System.Text.Encoding.Default;
}
}
}
}
可以到附件中下载