Article Title: Freedom to import your incremental data - based on conditions sqlserver table volume generated by the stored procedure INSERT statement enhancements
Keywords: mssql-scripter, SQL Server
Articles Category: Technology Share
Created: April 5 2020
_.-"\
_.-" \
,-" \
\ \
\ \Zoomla逐浪CMS\
\ \ web开发秘笈\ \
\ \ z01.com _.-;
\ \ _.-" :
\ \,-" _.-"
\( _.-"
`--"
- The rapid development of sensitive born
- Creating an intelligent storage process.
- Feature presentation
- Instructions
- Integrated in the waves CMS
- Support SQL2000
- Another example of Azeri group sharing
The rapid development of sensitive born
Software development, often generate data, backup and restore data migration, is a very important topic.
For small developers, often with full library coverage.
For millions, millions and even larger database, this operation is clearly used for a long time, and will affect the main scenario uses.
This time, we will need a list of all the data or query according to lead out, move to another of the same library structure
Currently there is no SQL Server-related tools to generate INSERT statements based on the query, the default sqlserver manager tool can generate a complete insert statements, only through third-party tools (third party tools) to achieve.
In fact, we can write a stored procedure script to achieve it.
Creating an intelligent storage process.
This script also many online, but the online script or the lack of some of the specifications and features, for example: I just want to export specific data query, online scripts are exporting the entire table data
If the table is large, it will have a significant impact on performance.
The complete syntax for creating stored procedures (for more than 2005 versions sql server):
-- Author: <Zoomla!逐浪CMS高端门户团队>
-- Blog: <http://www.z01.com/blog>
-- Create date: <2020/04/05>
-- Description: <根据查询条件导出表数据的insert脚本>
-- =============================================
CREATE PROCEDURE [dbo].[ZL_InsertGenerator]
(
@tableName NVARCHAR(MAX),
@whereClause NVARCHAR(MAX)
)
AS
--Then it includes a cursor to fetch column specific information (column name and the data type thereof)
--from information_schema.columns pseudo entity and loop through for building the INSERT and VALUES clauses
--of an INSERT DML statement.
DECLARE @string NVARCHAR(MAX) --for storing the first half of INSERT statement
DECLARE @stringData NVARCHAR(MAX) --for storing the data (VALUES) related statement
DECLARE @dataType NVARCHAR(MAX) --data types returned for respective columns
DECLARE @schemaName NVARCHAR(MAX) --schema name returned from sys.schemas
DECLARE @schemaNameCount int--shema count
DECLARE @QueryString NVARCHAR(MAX) -- provide for the whole query,
set @QueryString=' '
--如果有多个schema,选择其中一个schema
SELECT @schemaNameCount=COUNT(*)
FROM sys.tables t
INNER JOIN sys.schemas s ON t.schema_id = s.schema_id
WHERE t.name = @tableName
WHILE(@schemaNameCount>0)
BEGIN
--如果有多个schema,依次指定
select @schemaName = name
from
(
SELECT ROW_NUMBER() over(order by s.schema_id) RowID,s.name
FROM sys.tables t
INNER JOIN sys.schemas s ON t.schema_id = s.schema_id
WHERE t.name = @tableName
) as v
where RowID=@schemaNameCount
--Declare a cursor to retrieve column specific information
--for the specified table
DECLARE cursCol CURSOR FAST_FORWARD
FOR
SELECT column_name ,
data_type
FROM information_schema.columns
WHERE table_name = @tableName
AND table_schema = @schemaName
OPEN cursCol
SET @string = 'INSERT INTO [' + @schemaName + '].[' + @tableName + ']('
SET @stringData = ''
DECLARE @colName NVARCHAR(500)
FETCH NEXT FROM cursCol INTO @colName, @dataType
PRINT @schemaName
PRINT @colName
IF @@fetch_status <> 0
BEGIN
PRINT 'Table ' + @tableName + ' not found, processing skipped.'
CLOSE curscol
DEALLOCATE curscol
RETURN
END
WHILE @@FETCH_STATUS = 0
BEGIN
IF @dataType IN ( 'varchar', 'char', 'nchar', 'nvarchar' )
BEGIN
SET @stringData = @stringData + '''''''''+
isnull(' + @colName + ','''')+'''''',''+'
END
ELSE
IF @dataType IN ( 'text', 'ntext' ) --if the datatype
--is text or something else
BEGIN
SET @stringData = @stringData + '''''''''+
isnull(cast(' + @colName + ' as nvarchar(max)),'''')+'''''',''+'
END
ELSE
IF @dataType = 'money' --because money doesn't get converted
--from varchar implicitly
BEGIN
SET @stringData = @stringData
+ '''convert(money,''''''+
isnull(cast(' + @colName
+ ' as nvarchar(max)),''0.0000'')+''''''),''+'
END
ELSE
IF @dataType = 'datetime'
BEGIN
SET @stringData = @stringData
+ '''convert(datetime,''''''+
isnull(cast(' + @colName + ' as nvarchar(max)),''0'')+''''''),''+'
END
ELSE
IF @dataType = 'image'
BEGIN
SET @stringData = @stringData + '''''''''+
isnull(cast(convert(varbinary,' + @colName + ')
as varchar(6)),''0'')+'''''',''+'
END
ELSE --presuming the data type is int,bit,numeric,decimal
BEGIN
SET @stringData = @stringData + '''''''''+
isnull(cast(' + @colName + ' as nvarchar(max)),''0'')+'''''',''+'
END
SET @string = @string + '[' + @colName + ']' + ','
FETCH NEXT FROM cursCol INTO @colName, @dataType
END
--After both of the clauses are built, the VALUES clause contains a trailing comma which needs to be replaced with a single quote. The prefixed clause will only face removal of the trailing comma.
DECLARE @Query NVARCHAR(MAX) -- provide for the whole query,
-- you may increase the size
PRINT @whereClause
IF ( @whereClause IS NOT NULL
AND @whereClause <> ''
)
BEGIN
SET @query = 'SELECT ''' + SUBSTRING(@string, 0, LEN(@string))
+ ') VALUES(''+ ' + SUBSTRING(@stringData, 0,
LEN(@stringData) - 2)
+ '''+'')''
FROM ' +@schemaName+'.'+ @tableName + ' WHERE ' + @whereClause
PRINT @query
-- EXEC sp_executesql @query --load and run the built query
--Eventually, close and de-allocate the cursor created for columns information.
END
ELSE
BEGIN
SET @query = 'SELECT ''' + SUBSTRING(@string, 0, LEN(@string))
+ ') VALUES(''+ ' + SUBSTRING(@stringData, 0,
LEN(@stringData) - 2)
+ '''+'')''
FROM ' + @schemaName+'.'+ @tableName
END
CLOSE cursCol
DEALLOCATE cursCol
SET @schemaNameCount=@schemaNameCount-1
IF(@schemaNameCount=0)
BEGIN
SET @QueryString=@QueryString+@query
END
ELSE
BEGIN
SET @QueryString=@QueryString+@query+' UNION ALL '
END
PRINT convert(varchar(max),@schemaNameCount)+'---'+@QueryString
END
EXEC sp_executesql @QueryString --load and run the built query
--Eventually, close and de-allocate the cursor created for columns information.
Feature presentation
Here to declare that, if you have multiple schema, and each has the same table schema below, the script will generate a schema in which the table insert the following script
For example, I now have three schema, the following have the customer table
CREATE TABLE dbo.[customer](city int,region int)
CREATE SCHEMA test
CREATE TABLE test.[customer](city int,region int)
CREATE SCHEMA test1
CREATE TABLE test1.[customer](city int,region int)
When executing the script he would only generate the schema dbo table insert the following script
INSERT INTO [dbo].[customer]([city],[region]) VALUES('1','2')
This script has a flaw
Whether your field is what type of data tables, the guide came out only character
Table Structure
CREATE TABLE [dbo].[customer](city int,region int)
Guided by the insert script:
INSERT INTO [dbo].[customer]([city],[region]) VALUES('1','2')
Instructions
There are two ways
1, the whole guide table data
ZL_InsertGenerator 'customer', null
or:
ZL_InsertGenerator 'customer', ' '
2. The pilot data query
ZL_InsertGenerator 'customer', 'city=3'
or
ZL_InsertGenerator 'customer', 'city=3 and region=8'
Click, select All
Then copy
Create a new query window, and then paste
Integrated in the waves CMS
In fact, SQLServer has a lot of skills, such as using a combination of variables, dynamic updates, such as the following script:
set @最近查询时间 = '2020-04-5 19:35:57.000'
set @主表最近GID=(
select top 1 GeneralID from ZL_CommonModel left join ZL_C_image on ZL_CommonModel.ItemID=ZL_C_image.id where
UpDateTime<@最近查询时间 and ModelID=52 and Status=99 order by UpDateTime desc )
set @副表最近ID=(
select top 1 ID from ZL_CommonModel left join ZL_C_image on ZL_CommonModel.ItemID=ZL_C_image.id where
UpDateTime<@最近查询时间 and ModelID=52 and Status=99 order by UpDateTime desc)
select @最近查询时间 as 最近查询时间,@主表最近GID as 主表最近GID,@副表最近ID as 副表最近ID
Step Two: The following two ID numbers above the two transducers, a single query syntax obtained, and with:
SET IDENTITY_INSERT [Table] ON
SET IDENTITY_INSERT [Table] OFF
使用
ZL_InsertGenerator 'ZL_CommonModel','GeneralID>=9351'
go
ZL_InsertGenerator 'zl_c_image','id>=9352'
Support SQL2000
Finally, we can look at the code, very simple, if you want to support SQLServer2000, just change the code on it (although not much sql2000 users, but you can learn the appropriate roadmap).
Added: create a test table
CREATE TABLE testinsert (id INT,name VARCHAR(100),cash MONEY,dtime DATETIME)
INSERT INTO [dbo].[testinsert]
( [id], [name], [cash], [dtime] )
VALUES ( 1, -- id - int
'nihao', -- name - varchar(100)
8.8, -- cash - money
GETDATE() -- dtime - datetime
)
SELECT * FROM [dbo].[testinsert]
test
InsertGenerator 'testinsert' ,''
InsertGenerator 'testinsert' ,'name=''nihao'''
InsertGenerator 'testinsert' ,'name=''nihao'' and cash=8.8'
datetime there will be some type of problem
The results are automatically generated to help you convert
INSERT INTO [dbo].[testinsert]([id],[name],[cash],[dtime]) VALUES('1','nihao',convert(money,'8.80'),convert(datetime,'02 8 2015 5:17PM'))
Another example of Azeri group sharing
IF OBJECT_ID('spGenInsertSQL','P') IS NOT NULL
DROP PROC spGenInsertSQL
GO
CREATE proc spGenInsertSQL (@tablename varchar(256),@number BIGINT,@whereClause NVARCHAR(MAX))
as
begin
declare @sql varchar(8000)
declare @sqlValues varchar(8000)
set @sql =' ('
set @sqlValues = 'values (''+'
select @sqlValues = @sqlValues + cols + ' + '','' + ' ,@sql = @sql + '[' + name + '],'
from
(select case
when xtype in (48,52,56,59,60,62,104,106,108,122,127)
then 'case when '+ name +' is null then ''NULL'' else ' + 'cast('+ name + ' as varchar)'+' end'
when xtype in (58,61,40,41,42)
then 'case when '+ name +' is null then ''NULL'' else '+''''''''' + ' + 'cast('+ name +' as varchar)'+ '+'''''''''+' end'
when xtype in (167)
then 'case when '+ name +' is null then ''NULL'' else '+''''''''' + ' + 'replace('+ name+','''''''','''''''''''')' + '+'''''''''+' end'
when xtype in (231)
then 'case when '+ name +' is null then ''NULL'' else '+'''N'''''' + ' + 'replace('+ name+','''''''','''''''''''')' + '+'''''''''+' end'
when xtype in (175)
then 'case when '+ name +' is null then ''NULL'' else '+''''''''' + ' + 'cast(replace('+ name+','''''''','''''''''''') as Char(' + cast(length as varchar) + '))+'''''''''+' end'
when xtype in (239)
then 'case when '+ name +' is null then ''NULL'' else '+'''N'''''' + ' + 'cast(replace('+ name+','''''''','''''''''''') as Char(' + cast(length as varchar) + '))+'''''''''+' end'
else '''NULL'''
end as Cols,name
from syscolumns
where id = object_id(@tablename)
) T
IF (@number!=0 AND @number IS NOT NULL)
BEGIN
set @sql ='select top '+ CAST(@number AS VARCHAR(6000))+' ''INSERT INTO ['+ @tablename + ']' + left(@sql,len(@sql)-1)+') ' + left(@sqlValues,len(@sqlValues)-4) + ')'' from '+@tablename
print @sql
END
ELSE
BEGIN
set @sql ='select ''INSERT INTO ['+ @tablename + ']' + left(@sql,len(@sql)-1)+') ' + left(@sqlValues,len(@sqlValues)-4) + ')'' from '+@tablename
print @sql
END
PRINT @whereClause
IF ( @whereClause IS NOT NULL AND @whereClause <> '')
BEGIN
set @sql =@sql+' where '+@whereClause
print @sql
END
exec (@sql)
end
GO
Example calls
--非dbo默认架构需注意
--支持数据类型 :bigint,int, bit,char,datetime,date,time,decimal,money, nvarchar(50),tinyint, nvarchar(max),varchar(max),datetime2
--调用示例 如果top行或者where条件为空,只需要把参数填上null
spGenInsertSQL 'customer' --表名
, 2 --top 行数
, 'city=3 and didian=''大连'' ' --where 条件
--导出全表 where条件为空
spGenInsertSQL 'customer' --表名
, null --top 行数
,null --where 条件
INSERT INTO [Department] ([DepartmentID],[Name],[GroupName],[Company],[ModifiedDate]) values (1,N'售后部',N'销售组',N'中国你好有限公司XX分公司','05 5 2015 5:58PM')
INSERT INTO [Department] ([DepartmentID],[Name],[GroupName],[Company],[ModifiedDate]) values (2,N'售后部',N'销售组',N'中国你好有限公司XX分公司','05 5 2015 5:58PM')