T-SQL Recipes之Organizing and Archiving Data
The Problem
当我们处理存档数据或内存数据时,我们想要自定义命名表名,数据库,架构加上日期,时间,或者应用名时,用标准的TSQL来实现是比较困难的。
假设我们有一张日志表,增长速度异常快。但是你不需要超过一个星期的数据,应该怎么做呢?
表分区当然是最佳选择了,但只有企业版里面有这项功能,难道我们就没有其他选择了吗?当然是有的,先来准备点数据吧。
准备数据:
USE AdventureWorks2014;
GO
IF OBJECT_ID('dbo.Database_Log') IS NOT NULL
BEGIN
DROP TABLE dbo.Database_Log
END CREATE TABLE dbo.Database_Log
(
log_id INT NOT NULL
IDENTITY(1, 1)
CONSTRAINT PK_Database_Log PRIMARY KEY CLUSTERED ,
Log_Time DATETIME ,
Log_Data NVARCHAR(1000)
); DECLARE @datetime DATETIME = CURRENT_TIMESTAMP;
DECLARE @datediff TABLE
(
previous_hour SMALLINT
); DECLARE @count SMALLINT = 0;
WHILE @count <= 360
BEGIN
INSERT INTO @datediff
( previous_hour )
SELECT @count;
SELECT @count = @count + 1
END
SELECT @count = 0;
WHILE @count <= 1000
BEGIN
INSERT INTO Database_Log
( Log_Time ,
Log_Data
)
SELECT DATEADD(HOUR, -1 * previous_hour, CURRENT_TIMESTAMP) ,
CAST(DATEADD(HOUR, -1 * previous_hour,
CURRENT_TIMESTAMP) AS NVARCHAR)
FROM @datediff;
SELECT @count = @count + 1;
END
DECLARE @year_offset TINYINT = 5;
WHILE @year_offset > 0
BEGIN
INSERT INTO dbo.Database_Log
( Log_Time ,
Log_Data
)
SELECT TOP 10000
DATEADD(YEAR, -1 * @year_offset, Log_Time) ,
CAST(DATEADD(YEAR, -1 * @year_offset, Log_Time) AS NVARCHAR)
FROM Database_Log
SELECT @year_offset = @year_offset - 1;
END
The Solution
假设我们存档数据格式是,每年为数据库,每星期为一个表。如:dbo.database_log_2016为数据库,其中 dbo.database_log_2016_32为表。
我们动态SQL应该如何实现呢? 先整理一下思路
- 获取日志记录通过时间段
- 创建数据库或表(如果他们不存在)
- 进行插入操作
- 删除原始数据
代码:
DECLARE @sql_command NVARCHAR(MAX);
DECLARE @parameter_list NVARCHAR(MAX) = '@start_of_week DATETIME, @end_of_week DATETIME';
DECLARE @min_datetime DATETIME; SELECT @min_datetime = MIN(Log_Time)
FROM Database_Log; DECLARE @previous_min_time DATETIME = '1/1/1900';
DECLARE @start_of_week DATETIME = CAST(DATEADD(dd, -1 * (DATEPART(dw, @min_datetime) - 1), @min_datetime) AS DATE);
DECLARE @end_of_week DATETIME = DATEADD(WEEK, 1, @start_of_week);
DECLARE @current_year SMALLINT;
DECLARE @current_week TINYINT;
DECLARE @database_name NVARCHAR(128);
DECLARE @table_name NVARCHAR(128); WHILE (@previous_min_time <> @min_datetime)
BEGIN
SELECT @current_year = DATEPART(YEAR, @start_of_week);
SELECT @current_week = DATEPART(WEEK, @start_of_week);
SELECT @database_name = 'Database_Log_' + CAST(@current_year AS NVARCHAR); -- Create the yearly database if it does not already exist
SELECT @table_name = 'Database_Log_' + CAST(@current_year AS NVARCHAR) + '_' + CAST(@current_week AS NVARCHAR)
IF NOT EXISTS(SELECT *FROM sys.databases WHERE databases.name = @database_name)
BEGIN
SELECT @sql_command = 'CREATE DATABASE [' + @database_name + ']';
EXEC sp_executesql @sql_command; END -- Create the weekly table if it does not already exist
SELECT @sql_command = '
USE [' + @database_name + '];
IF NOT EXISTS (SELECT * FROM sys.tables WHERE tables.name = ''' + @table_name + ''')
BEGIN
CREATE TABLE [dbo].[' + @table_name + ']
(Log_Id INT NOT NULL CONSTRAINT PK_Database_Log_' + CAST(@current_year AS NVARCHAR) + '_' + CAST(@current_week AS NVARCHAR) + ' PRIMARY KEY CLUSTERED,
Log_Time DATETIME,
Log_Data NVARCHAR(1000));
END' EXEC sp_executesql @sql_command; SELECT @sql_command = '
INSERT INTO [' + @database_name + '].[dbo].[' + @table_name + ']
(Log_Id, Log_Time, Log_Data) SELECT
Log_Id,
Log_Time,
Log_Data
FROM AdventureWorks2014.dbo.Database_Log
WHERE
Log_Time >= @start_of_week
AND Log_Time <= @end_of_week
AND Log_Time < DATEADD(WEEK, -1, CURRENT_TIMESTAMP); DELETE
FROM AdventureWorks2014.dbo.Database_Log
WHERE
Log_Time >= @start_of_week
AND Log_Time <= @end_of_week
AND Log_Time < DATEADD(WEEK, -1, CURRENT_TIMESTAMP);' EXEC sp_executesql @sql_command,@parameter_list,@start_of_week,@end_of_week SELECT @previous_min_time = @min_datetime; SELECT @min_datetime = MIN(Log_Time)
FROM Database_Log; SELECT @start_of_week = CAST(DATEADD(dd, -1 * (DATEPART(dw, @min_datetime) - 1), @min_datetime) AS DATE); SELECT @end_of_week = DATEADD(WEEK, 1, @start_of_week); END
结语
善使用动态TSQL会让你在工作中的心情变得更美好,当然也可能更恶劣。以后还会讲到如何使用动态TSQL来备份数据库,索引管理。
T-SQL Recipes之Organizing and Archiving Data的更多相关文章
- SQL2008安装时,“provider: 命名管道提供程序, error: 40 - 无法打开到 SQL Server 的连接) (.Net SqlClient Data Provider)” 错误的解决方案
错误提示: 在与 SQL Server 建立连接时出现与网络相关的或特定于实例的错误.未找到或无法访问服务器.请验证实例名称是否正确并且 SQL Server 已配置为允许远程连接. (provide ...
- SQL Fundamentals:Restricting and Sorting Data限制和排序数据(FROM-WHERE-SELECT-ORDER BY)
SQL Fundamentals || Oracle SQL语言 控制操作的显示列:基本的SELECT语句 控制行:限定查询和排序显示 分组统计查询 限定查询:WHERE字句 排序显示:ORDER B ...
- SQL Server2008 错误源:.net SqlClient data provider的解决方法
今天下午直接在SQL Server 2008的Microsoft SQL Server Management Studio 中修改一张表中某个字段, 不管是删除字符还是添加都提示下面的错误. 网上很多 ...
- 20180820 SQL 提示Error: String or binary data would be truncated
Error: String or binary data would be truncated,错误,是因为栏位给出的长度不够,增加初始化长度就可以了. 除了创建表的增加长度情况,还有一种是,SELE ...
- 未找到或无法访问服务器。请验证实例名称是否正确并且 SQL Server 已配置为允许远程连接。 (provider: Named Pipes Provider, error: 40 - 无法打开到 SQL Server 的连接) (.Net SqlClient Data Provider)
今天连接服务器的SQL Server 遇到了一个很经典的问题 之前也曾多次遇到过 这次记录一下 按照之前经验 首先 开启了服务中的 SQL Server(MSSQLSERVER)和ASP.NET St ...
- Spark SQL External Data Sources JDBC简易实现
在spark1.2版本中最令我期待的功能是External Data Sources,通过该API可以直接将External Data Sources注册成一个临时表,该表可以和已经存在的表等通过sq ...
- 转载:Character data is represented incorrectly when the code page of the client computer differs from the code page of the database in SQL Server 2005
https://support.microsoft.com/en-us/kb/904803 Character data is represented incorrectly when the cod ...
- sql是如何执行一个查询的!
引用自:http://rusanu.com/2013/08/01/understanding-how-sql-server-executes-a-query/ Understanding how SQ ...
- [Windows Azure] Data Management and Business Analytics
http://www.windowsazure.com/en-us/develop/net/fundamentals/cloud-storage/ Managing and analyzing dat ...
随机推荐
- TCP/IP模型详解
上述为TCP/IP的协议模型,主机到网络层又被称为网络接口层,网络互联层又被称为网间层. 网络接口层:实际上,TCP/IP参考模型并没有真正描述这一层的实现,只是要求能够提供给其上层一个访问接口,以便 ...
- How the problem solved about " Dealing with non-fast-forward errors"
Recently ,I got confused When I use git to push one of my project. The problem is below: And I Foun ...
- CSS导航菜单水平居中的多种方法
CSS导航菜单水平居中的多种方法 在网页设计中,水平导航菜单使用是十分广泛的,在CSS样式中,我们一般会用Float元素或是「display:inline-block」来解决.而今天主要讲解如何让未知 ...
- 全排列算法的JS实现
问题描述:给定一个字符串,输出该字符串所有排列的可能.如输入“abc”,输出“abc,acb,bca,bac,cab,cba”. 虽然原理很简单,然而我还是折腾了好一会才实现这个算法……这里主要记录的 ...
- C#操作XML总结
1.using System.Xml; using System.Xml; //初始化一个xml实例 XmlDocument xml=new XmlDocument(); //导入指定xml文件 xm ...
- ACM/ICPC 之 中国剩余定理+容斥原理(HDU5768)
二进制枚举+容斥原理+中国剩余定理 #include<iostream> #include<cstring> #include<cstdio> #include&l ...
- Matlab 周期方波信号傅里叶级数展开
方波信号为: 傅里叶级数展开为: 程序运行结果: 程序代码: clear x = -6:0.01:6; T = 4; f = x; for N = 1:length(f) temp = rem(abs ...
- JavaScript中的面向对象
//简单的面向对象 function 构造函数(){ this.属性; } //写在构造函数里面的属性一般为公共属性,或者通过传值进行改变. 构造函数.原型.方法 = function(){}; // ...
- 【转】Caffe初试(七)其它常用层及参数
本文讲解一些其它的常用层,包括:softmax-loss层,Inner Product层,accuracy层,reshape层和dropout层及它们的参数配置. 1.softmax-loss sof ...
- android studio使用部分报错处理
1.android studio 导入项目时Error:SSL peer shut down incorrectly 今天导入一个项目到studio,显示在下载一个一个1.1.0-rc4的东西. 过了 ...