返回首页

知识点

递归取数

;WITH ent

AS (SELECT EntryID,0 AS _parentId

FROM #LevelOne

UNION ALL

SELECT a.EntryID,a._parentId

FROM #Result a

INNER JOIN ent b ON a._parentId=b.EntryID

)

SELECT DISTINCT EntryID INTO #TopToBottom FROM ent

其实UNION ALL前的语句相当于初始化值,然后决定这些值是向上OR向下递归


知识点

DECLARE @sql VARCHAR(1000)

SET @sql='SELECT

1234 AS Col1

4321 AS Col2'

PRINT @sql

EXEC (@sql)

动态别名只能用动态语句


知识点

反转字符串

SELECT REVERSE('abc')


高速

--查询死锁

select request_session_id 锁表进程,OBJECT_NAME(resource_associated_entity_id) 被锁表名

from sys.dm_tran_locks where resource_type='OBJECT'

--处理死锁

declare @spid int

Set @spid=60 --锁表进程

declare @sql varchar(1000)

set @sql='kill '+cast(@spid as varchar)

exec (@sql)


知识点

Between..AND..

包括两边的边界值 可以为数值、文本、日期(注意是当天0点)


知识点

使用Exists条件而不用inner join 或 其他join 是因为可能有多条匹配

包括两边的边界值 可以为数值、文本、日期(注意是当天0点)


高速

游标样例

DECLARE @ProCode NVARCHAR(50);
DECLARE @UserId NVARCHAR(50);
DECLARE @Count INT;
BEGIN
DECLARE Update_cursora CURSOR LOCAL static read_only forward_only FOR
select ProductCodeId,UserCode from Product_User_Relation where DeleteFlag =0 and ProductCodeId like '9%' ---And UserCode='duanjin 06481'
OPEN Update_cursora;
FETCH NEXT FROM Update_cursora INTO @ProCode,@UserId
WHILE @@FETCH_STATUS = 0
BEGIN
select * into #temp from (
select ProID,ProCode FROM dbo.ProductInfo where ParentCode=@ProCode --A
--B
union all
select ProID,ProCode FROM ProductInfo where ParentCode in(
select ProCode from dbo.ProductInfo where ParentCode=@ProCode
)
union all
--C
select ProID,ProCode FROM ProductInfo where ParentCode in(
select ProCode from ProductInfo where ParentCode in(
select ProCode from ProductInfo where ParentCode=@ProCode
)
)
)pro
where not exists(select 1 from Product_User_Relation where UserCode=@UserId And pro.ProCode=ProductCodeId);
DROP TABLE #temp
FETCH NEXT FROM Update_cursora INTO @ProCode,@UserId
END;
CLOSE Update_cursora;
DEALLOCATE Update_cursora;
END;

高速

压缩日志

USE[PersonalInput]
GO
ALTER DATABASE PersonalInput SET RECOVERY SIMPLE WITH NO_WAIT
GO
ALTER DATABASE PersonalInput SET RECOVERY SIMPLE --简单模式
GO
USE PersonalInput
GO
DBCC SHRINKFILE (N'PersonalInput_log' , 2, TRUNCATEONLY) --设置压缩后的日志大小为2M,可以自行指定
GO
USE[PersonalInput] -- 注意要把使用的数据库不是master 还原为完整模式
GO
ALTER DATABASE PersonalInput SET RECOVERY FULL WITH NO_WAIT
GO
ALTER DATABASE PersonalInput SET RECOVERY FULL --还原为完全模式
GO

高速

更新统计信息

--更新库所有表的统计信息
--EXEC sp_updatestats
go
--更新某一个表的统计信息
UPDATE STATISTICS Sales.SalesOrderDetail;
GO
--更新某一个索引的统计信息
UPDATE STATISTICS Sales.SalesOrderDetail AK_SalesOrderDetail_rowguid;

高速

查询表字段

select * from sys.columns where object_id=object_id('table_name')
sys.columns - 保存当前数据库中所有表的所有字段
object_id('objectname') 返回对象的ID值

高速

表更新相关

--根据不同条件 把某列值更新为其他值 UPDATE Table SET Column= CASE WHEN Column=Value THEN Value WHEN Column=Value THEN Value END --根据两个表关联条件 把其中一个表中字段数据更新到另一个表的字段中 UPDATE TableA SET TableA.Column=B.Column FROM TableB B WHERE TableA.Column=B.Column -- 使用别名 UPDATE ent SET EntryCName=bak.EntryCName, PriorityLevel=bak.PriorityLevel, Remark=bak.Remark, Description=bak.Description, Status=0, DeleteFlag=0 FROM Sol_Entry bak INNER JOIN Sol_EntryRelation rel ON bak.EntryID=rel.BackEntryID INNER JOIN Sol_Entry ent ON ent.EntryID=rel.EntryID WHERE ent.BlID=4 AND bak.Status=-2 --update 和from 来自同一个表时 update后必须用别名 from 后用inner join UPDATE col SET col.Name=bak.Name, col.Description=bak.Description, col.Status=0 FROM Sol_EntryColName bak INNER JOIN Sol_EntryColName col ON col.ColID=bak.BackColID WHERE bak.Status=-2 AND Sol_EntryColName.BlID=:BlID

高速

表删除相关

DELETE ent FROM TableA ent INNER JOIN TableB rel ON ent.ID=rel.ID WHERE rel.Type=1

知识点

查询表上依赖关系

在表上右键 有个依赖关系 点击后能看到依赖的表,函数,存储过程,视图 如果某个字段更新了(字段大小改变等) 像视图之类的依赖关系必须更新
额外注意存储过程中遇到拼接字符串的表名是查询不到依赖关系的,只有sql语句中可以查到

高速

创建存储过程

-- ============================================= -- Author: -- Create date: -- Description: 获取产品工程类型数据及产品列 -- ============================================= ALTER PROCEDURE [dbo].[P_GetProductCol] @blId INT, --基线id @userId NVARCHAR(100), --用户工号 e.g ys2338 ,17333 @proAttr NVARCHAR(100), --产品列内容 查询条件,传递的是字典表的ConsValue,e.g:UnSupport,Other @isEdit bit,--0:不是编辑 1是编辑 @showType INT -- 类型 0:产品列名称显示 1:使用Pro_ 列ID (为前端处理方便) AS BEGIN DECLARE @procol VARCHAR(max) --有权限的产品列 DECLARE @sql VARCHAR(max) --拼接的sql exec(@sql) --select @sql END;

知识点

CHARINDEX的使用

select charindex('a','abca') result :1
从左到右只返回第一个匹配到的节点,下标从1开始 该函数无法使用索引

小坑

left join 的使用

一个主表main left join 业务表T1 如要保持主表完整性,筛选条件要跟在T1后,不能放到主表where 条件中,否则是筛选主表了

高速

检查是否有临时表

if object_id(N'tempdb..#K_Temp',N'U') is not null begin Table #K_Temp print '删除成功' end

高速

查询表创建时间

select distinct xtype from sysobjects -- select name,crdate from sysobjects where xtype = 'TF' --表值函数 -- select name,crdate from sysobjects where xtype = 'FN' --标量值函数 -- select name,crdate from sysobjects where xtype = 'P' --存储过程 -- select name,crdate from sysobjects where xtype = 'U' --表 -- select name,crdate from sysobjects where xtype = 'V' -- 视图

知识点

行转列函数定义

SELECT , [first pivoted column] AS , [second pivoted column] AS , … [last pivoted column] AS FROM (<查询表或者子查询作为数据源>) AS 表别名 PIVOT ( <聚合函数>(<被聚合的列>)(原有的数据列) FOR [<待转换的列名称,此列的多个唯一值将被转换为列标题>(转换前列名)] IN ( [first pivoted column], [second pivoted column], … [last pivoted column]) ) AS <旋转表的别名> <可选的排序子句 order by >;

高速

行转列例子一则

if object_id('tempdb..#test') is not null drop table #test create table #test ( 事项名称 varchar(200), 年月 varchar(7), 受理数量 int , 办结数量 int ) insert into #test select '注销','2019-01',77,77 union all select '注销','2019-02',66,77 union all select '延续','2019-03',16,16 union all select '注销','2019-04',16,16 union all select '延续','2019-04',120,115 --select *from #test declare @event varchar(3000)='',@sql varchar(3000)='',@queryexp varchar(3000)='' if object_id('tempdb..#hbTab') is not null drop table #hbtab select 事项名称,(年月+'_受理') as [year],受理数量,年月 into #hbtab from #test --列转行 insert into #hbtab select 事项名称,(年月+'_办结') as [year],办结数量,年月 from #test --获取行的属性 --select *from #hbtab select @event=@event+',['+[year]+']' from (select distinct [year] from #hbtab) a order by [year] select @queryexp=@queryexp+',max(['+[year]+']) as '+'['+[year]+']' from (select distinct [year] from #hbtab) a order by [year] select @queryexp=right(@queryexp,len(@queryexp)-1) select @event=right(@event,len(@event)-1) --select *from #hbtab order by year set @sql='select 事项名称,'+@queryexp+' from( select 事项名称,'+@event +'from #hbtab a pivot (max(受理数量) for year in('+@event+') ) as pv ) b group by 事项名称' print @sql exec(@sql)
原文:https://blog.csdn.net/u010892506/article/details/89458862

高速

逗号分隔的字符串转换为Table数据

DECLARE @person VARCHAR(300)='liuyujing,liufeng,zhaiguoxiu' DECLARE @tmpsql NVARCHAR(4000) SELECT @tmpsql='SELECT ''' + REPLACE(@person,',',''' UNION ALL SELECT ''')+ '''' PRINT @tmpsql exec sp_executesql @tmpsql

临时表或表无索引时 插入有序数据(按字符串列排序) 在临时表或表中是无序的

1.可以创建索引解决 Create Clustered Index IDX_Table_Name ON Table(name)
2.可以引入新的排序后的序号列解决 select ROW_NUMBER() over(order by oi.CreatedOn desc) as row_num,oi.Id,odi.Amount...

字符串变量为null的问题

定义变量后declare @str nvarchar(10) 不赋值则是null 如果再有字符串相关的拼接操作 则结果很有可能都为null
所以需要设置set @str=''

知识点

函数DatePart 返回日期/时间单独部分 DATEPART(datepart,date)

年 yy, yyyy
季度 qq, q
月 mm, m
年中的日 dy, y
日 dd, d
周 wk, ww
星期 dw, w
小时 hh
分钟 mi, n
秒 ss, s
毫秒 ms
微妙 mcs
纳秒 ns

问题

查询处理器用尽了内部资源,无法生成查询计划

在项目中动态拼接sql语句,使用union all连接结果集,每个查询语句都使用了in(几百个数值)
SELECT AA FROM T1 WHERE aa IN(1,2,3,4..............................) UNION ALL SELECT AA FROM T2 WHERE aa IN(1,2,3,4..............................)
主要是因为IN中数据量太大了 解决方案:使用临时表把in语句改成EXISTS语句

知识点

嵌套的事务

1.如果出现rollback tran 之类的是回滚所有 并不区分是内层还是外层 后面语句如果再有commit或rollback 会报错:‘COMMIT TRANSACTION 请求没有对应的 BEGIN TRANSACTION’ 所以内层rollback 往往跟return
2.如果没有save tran innerTran 想回滚内层 rollback tran innerTran 是报错的
3.内层save tran innerTran1 或save tran innerTran2 可以使用rollback tran innerTran1(回到这个状态)
4.只要外层rollback tran 内层不管什么状态都是回滚

知识点

select * from 多个表的写法

from 多个表后没有添加任何的关联条件 其实就是笛卡尔积 应避免该种写法 如果遇到 大多是错误的写法

知识点

Merge 语句的使用

根据与源表联接的结果,对目标表运行插入、更新或删除操作。 语法如下:
[ WITH <common_table_expression> [,...n] ] MERGE [ TOP ( expression ) [ PERCENT ] ] [ INTO ] <target_table> [ WITH ( <merge_hint> ) ] [ [ AS ] table_alias ] USING <table_source> [ [ AS ] table_alias ] ON <merge_search_condition> [ WHEN MATCHED [ AND <clause_search_condition> ] THEN <merge_matched> ] [ ...n ] [ WHEN NOT MATCHED [ BY TARGET ] [ AND <clause_search_condition> ] THEN <merge_not_matched> ] [ WHEN NOT MATCHED BY SOURCE [ AND <clause_search_condition> ] THEN <merge_matched> ] [ ...n ] [ <output_clause> ] [ OPTION ( <query_hint> [ ,...n ] ) ] ;
其中 using 后的源 可以是多个表的关联;注意最后需要有分号
<merge_matched>::= { UPDATE SET <set_clause> | DELETE } <merge_not_matched>::= { INSERT [ ( column_list ) ] { VALUES ( values_list ) | DEFAULT VALUES } }
注意:无论哪种操作,都只能操作目标表;当为NOT MATCHED BY SOURCE 状态时,不能使用源表中的数据,即不能更新为源表中某个字段的内容,但可以指定一个常量
举个例子
merge TestB T using TestC S on T.entryid=s.entryid when matched then update set T.Des=S.Des when not matched then insert values(S.entryid,S.Des) when not matched by source then delete ;

知识点

Stuff 函数

它从第一个字符串的开始位置删除指定长度的字符;然后将第二个字符串插入到第一个字符串的开始位置。
语法:STUFF(character_expression , start , length , replaceWith_expression)
start 参数: 一个整数值(从1开始),指定删除和插入的开始位置。start 的类型可以是 bigint。
SELECT STUFF('abc',2,1,'EFG')
结果:aEFGc

知识点

For XML Path

该方式其实是用xml节点名称包装记录,展示为一条数据
默认情况下,最外层节点为Row,内层节点则是列的名称,举个例子:
SELECT T1 FROM TABLE For XML Path 的结果为:
<row> <T1>1</T1> <T1>2</T1> </row>
也可以用For XML Path('') 不要最外层的row节点
当选择的列有计算时,如数字的加减,字符串的拼接,则该列被当作新列,没有名称!所以For XML Path 的用途一般为高效拼接字符串,举个例子:
SELECT STUFF((SELECT ','+T1 From TABLE For XML Path('')),1,1,'')
该语句的作用为用逗号分隔T1列中拼接的内容

知识点

表中一列字符串累加的处理

e.g 从表T中选择Name列,Name列有三行值为a,b,c
declare @str nvarchar(1000) SET @str='' select @str= @str+ CONVERT(nvarchar(50), ISNULL(Name,' ')) +',' from T select @str
结果:a,b,c,
该方法与For XML Path的结果基本相同,但没有它高效

知识点

变量处理列内容累加

比如,用分号分隔一列内容累加
declare @str nvarchar(1000) select @str= CONVERT(nvarchar, ISNULL(@str,''))+CONVERT(nvarchar, ISNULL(column,' ')) +';' from table select @str
注意 1.需要定义变量存放值
2.不能从table中选择多列,否则语法有错误

知识点

必须指定别名的情况

select t.* from(select 1 as t1) t
这种选择常量的,内层必须指定别名 否则会报:没有为 't' 的列 1 指定任何列名称

知识点

优化经验

1.先弄懂业务 以及表之间的关系 确保各条件分支业务逻辑正确
2.通过查看预读,逻辑读,物理读次数找到耗时点
3.对于临时表 可以建立索引加快查询 (优化近20s)
4.查看执行计划 找出消耗占比大的步骤
5.发现其中有个Row Count Spool 占比较大 经过查阅资料 发现是与统计相关字段未建立索引 建立索引后优化27s左右
6.发现有复杂的更新子查询 但是不同更新数据又有上下父子级联动数据影响 检查后当前业务逻辑正确所以优化结束 增加参数过滤数据
7.对比 优化前1m多 优化后10s多

知识点

ROW_NUMBER()用法

语法: ROW_NUMBER() OVER ( [ PARTITION BY value_expression , ... [ n ] ] order_by_clause )
使用方式一:
select t.* from( select ROW_NUMBER() over(order by id desc) as rownum,* from TestA ) t where rownum between 2 and 3 order by T4
使用方式二:
;with orderSection as ( select ROW_NUMBER() OVER(order by id desc) rownum,* from TestA ) select * from [orderSection] where rownum between 2 and 3
获取rownumber中排序的顺序 和主sql中的顺序应该一致 否则rownumber可能会不连续 感觉也没有不一致的场景。
增加PARTITION BY 的用法
若是在 T5 列上添加 PARTITION BY 子句,按照order by的顺序当 T5 值发生更改时将重新开始编号。 其实也是先按照T5排序,然后再按照T1排序
select ROW_NUMBER() over(partition by T5 order by T1 desc) as rownum,ID,T1,T5 from TestA

知识点

Rank()用法

语法: RANK() OVER ( [ partition_by_clause ] order_by_clause )
rank函数用于返回结果集的分区内每行的排名, 行的排名是相关行之前的排名数加一。简单来说rank函数就是对查询出来的记录进行排名,与row_number函数不同的是,rank函数考虑到了over子句中排序字段值相同的情况,如果使用rank函数来生成序号,over子句中排序字段值相同的序号是一样的,后面字段值不相同的序号将跳过相同的排名号排下一个,也就是相关行之前的排名数加一,可以理解为根据当前的记录数生成序号,后面的记录依此类推。
如 1,1,3,3,3,6

知识点

DENSE_RANK()用法

语法: DENSE_RANK() OVER ( [ ] < order_by_clause > )
dense_rank函数的功能与rank函数类似,dense_rank函数在生成序号时是连续的,而rank函数生成的序号有可能不连续。dense_rank函数出现相同排名时,将不跳过相同排名号
如 1,1,2,2,2,3

知识点

NTILE()用法

语法:NTILE (integer_expression) OVER ( [ ] < order_by_clause > )
参数 integer_expression:一个正整数表达式,用于指定每个分区必须被划分成的组数。 integer_expression 可以是 int 或 bigint 类型 。
关于该函数的说明:
如果分区的行数不能被 integer_expression 整除,则将导致一个成员有两种大小不同的组。 按照 OVER 子句指定的顺序,较大的组排在较小的组前面。 例如,如果总行数是 53,组数是 5,则前三个组每组包含 11 行,其余两个组每组包含 10 行。 另一方面,如果总行数可被组数整除,则行数将在组之间平均分布。 例如,如果总行数为 50,有五个组,则每组将包含 10 行。
select NTILE(2) over(order by T1 desc) as rownum,ID from TestA
分为两组 从1开始
1,1,2,2 或 1,1,1,2,2

知识点

SELECT - Order by 子句

语法:
ORDER BY order_by_expression [ COLLATE collation_name ] [ ASC | DESC ] [ ,...n ] [ <offset_fetch> ] <offset_fetch> ::= { OFFSET { integer_constant | offset_row_count_expression } { ROW | ROWS } [ FETCH { FIRST | NEXT } {integer_constant | fetch_row_count_expression } { ROW | ROWS } ONLY ] }
举个例子
ORDER BY EntryOrder OFFSET 1 ROWS FETCH NEXT 10 ROWS ONLY
其中OFFSET后参数实际中可以为( @PageIndex * @PageSize ) - @PageSize
NEXT后参数可以为 @PageSize

知识点

链接服务器

添加链接服务器:exec sp_addlinkedserver '链接服务器名','','SQLOLEDB','服务器名或ip地址'
添加链接服务器登录方式:exec sp_addlinkedsrvlogin '链接服务器名','false',null,'数据库账号','密码'
删除链接服务器:exec sp_dropserver '链接服务器名称', 'droplogins' 第一个参数是要删除的链接服务器;第二个参数作用是连带删除该链接服务器登录映射
--如果存在则删除 IF EXISTS (SELECT srvname FROM master.dbo.sysservers srv WHERE srvid != 0 AND srvname = N'RDMDSDB') EXEC master.dbo.sp_dropserver @server=N'RDMDSDB', @droplogins='droplogins' --增加链接服务器 EXEC sp_addlinkedserver @server='RDMDSDB', --被访问的服务器别名 @srvproduct='sqlserver', --SqlServer默认不需要写 @provider=N'SQLNCLI', --不同的库都是不一样的,OLE DB字符 @datasrc='nrdmdsdb.h3c.com'--要访问的服务器 GO --增加登录方式 EXEC sp_addlinkedsrvlogin @rmtsrvname='RDMDSDB', --被访问的服务器别名 @useself='false', --固定这么写 @locallogin=null, --本地操作应户名 @rmtuser='ISE_RDMDSNEW', --被访问的服务器用户名 @rmtpassword='NrdmdsDb4ISE43'--被访问的服务器用密码 GO

知识点

查看/操作 tempdb库

查看tempdb当前大小:exec sp_helpdb tempdb
对tempdb进行收缩:
use tempdb go dbcc shrinkfile(tempdev, 1024) --收缩文件 use tempdb go dbcc shrinkfile(templog, 512)--收缩日志

问题

不能创建大小为 9283 的行,该大小大于所允许的最大行大小 8060

每个表可以有1024列,表的行数及总大小仅受可用存储空间的限制, 每行最多可以存储8,060字节。
对于列过多导致行数据超过限定的情况,尽量不把数据放入表或临时表,直接取数或用CTE代替

知识点

统计某个字段中某个字符的个数

方法是把目标字符替换为空字符,再用原字符-替换后字符得到长度即可。
举个例子:统计“/”字符的个数
select len('888/6/35/1101')-len(replace('888/6/35/1101','/','')) from xxx

知识点

数据库作业用脚本展示 提升效率

原文链接:https://www.cnblogs.com/footleg/p/7131501.html

知识点

微软专家 一句话sql优化建议

1.in 中的值较多 建议反倒临时表中 2.select 中尽量不使用子查询 3.临时表 可以建索引 4.使用正向逻辑代替否定逻辑 e.g left join 替换 not in, not exits 5.isnull 函数用不到索引 应使用col is null or col=''

知识点

哪些情况需要建立索引

1.主键自动建立唯一索引 2.频繁作为查询条件的字段应该创建索引 3.查询中与其它表关联的字段,外键关联建立索引 4.频繁更新的字段不适合建索引(每次更新不单单是更新了记录还会更新索引) 5.where条件中用不到的字段不建索引 6.单键/组合索引(在高并发下建议建组合索引) 7.查询中排序的字段,排序字段通过索引去访问提高排序速度 8.查询中统计或分组字段
原文链接:https://blog.csdn.net/a332056918/article/details/81916255

知识点

子查询

子查询结果返回一个值(单行单列) 可以使用的运算符:><>=<==<>
select * from TestA where T1 > ( select T1 from TestA where ID=2) ;
子查询结果返回多行(多行单列) 可以使用运算符:>ALL >ANY <ALL <ANY in
select * from TestA where T1>All(select T1 from TestA where ID=2) select * from TestA where T1>Any(select T1 from TestA where ID=2)
子查询结果返回多行多列 在sqlserver中 需要使用运算符checksum辅助 oracle或Mysql中直接用(ColumnA,ColumnB)就可以
select * from TestA where checksum(T1,T2) in ( select checksum(T1,max(T2)) from TestA group by T1 )
也可以用Exists 关键字 内外关联字段处理
关联子查询:关联子查询的执行依赖于外部查询的数据,外部查询执行一行,子查询就执行一次。所以关联子查询,先执行主查询,再执行子查询
非关联子查询:是独立于外部查询的子查询,子查询总共执行一次,执行完毕后将值传递给外部查询。所以非关联子查询,先执行子查询,再执行主查询

表中的字段最长为128 如果超出则会报错

实际中的报错:
消息 103,级别 15,状态 4,第 194 行 以 '1_solPart_15_LS-5130S-28S-EI;LS-5130S-28P-EI;LS-5130S-28P-HPWR-EI;LS-5130S-10P-HPWR-EI;S5110V2-28P-HPWR;5110V2-52P-PWR;S5120V2-2' 开头的 标识符 太长。最大长度为 128。
在有类似行转列操作时,部分数据由用户自己输入容易引发该问题。
最后解决办法是不使用名称而改用id作为列名,取出数据后到程序中再根据id找到名称。

知识点

使用try catch 以及相关报错信息

使用try catch的结构如下:
BEGIN TRY 需要捕捉异常的程序块 END TRY BEGIN CATCH 异常处理块 END CATCH
ERROR_NUMBER() --返回错误代码
ERROR_SEVERITY() --返回错误的严重级别
ERROR_STATE() --返回错误的状态码
ERROR_MESSAGE() --返回错误的完整信息

知识点

数据随机排序 或 随机取数

这里主要用到了NewID() 函数,把它放在Order By 后即可:
SELECT * FROM TableA ORDER BY NEWID()

报错

已超过了锁请求超时时段 1222

现象:
1.执行truncate语句 一直得不到结果(应该很快完成才对)
2.所有表都刷新不出来
定位问题: 那么只有一种可能就是该TRUNCATE语句位于事务里面,而该事务由于逻辑原因等一直没有提交或回滚。
参考:https://www.cnblogs.com/kerrycode/p/4502164.html

错误一则

Insert语句与Foreign Key约束冲突

问题分析:
1.一般出现在表中建了外键的情况
2.该问题是在外键表中插入了不存在的主表的主键值
举例:
Create Table TestA ( ID int primary key )
Create Tabel TestB ( ID int primary key, WID int )
Constraint FK_TestB_TestA(ID) References TestA
执行如下语句:
Insert Into TestB Select 1,999
会报INSERT 语句与FOREIGN KEY约束FK_TestB_TestA冲突,该冲突发生在数据库XXXX,表dbo.TestA,Column 'ID'。语句已终止

知识点

设置自增表种子值

USE AdventureWorks2012;
GO
DBCC CHECKIDENT ('Person.AddressType', RESEED, 10);
GO

知识点

查询数据库中表,视图,存储过程,函数,触发器,用户定义类型的信息

所有表信息

SELECT name,create_date,modify_date FROM sys.objects WHERE type = 'U' order by name

所有触发器

SELECT name AS 'Trigger Name', OBJECT_NAME(parent_id) AS 'Table Name',create_date,modify_date FROM sys.triggers;

所有视图信息

SELECT name,create_date,modify_date FROM sys.objects WHERE type = 'V' order by name

所有存储过程信息

SELECT name,create_date,modify_date FROM sys.objects WHERE type = 'P' order by name

所有标量值函数

SELECT name,create_date,modify_date FROM sys.objects WHERE type = 'FN' AND is_ms_shipped = 0 order by name

所有表值函数

SELECT name,create_date,modify_date FROM sys.objects WHERE type = 'TF' UNION SELECT name,create_date,modify_date FROM sys.objects WHERE type = 'IF' order by name

所有用户定义表类型

SELECT name FROM sys.table_types WHERE is_user_defined = 1

知识点

查询一个对象是什么类型

SELECT OBJECT_NAME(object_id) AS ObjectName, CASE WHEN type = 'U' THEN 'Table' WHEN type = 'V' THEN 'View' WHEN type = 'P' THEN 'Stored Procedure' ELSE '' END AS ObjectType FROM sys.objects WHERE name IN ('对象名');

知识点

日期处理相关函数

YEAR() 函数:返回日期的年份

Year('2024-1-1') 结果:2024

MONTH() 函数:返回日期的月份。

Year('2024-1-1') 结果:1

DATEDIFF(interval,startdate,enddate) 函数:计算两个日期之间的差异。其中interval可以是年y,季度q,月m,日d,周w,小时h,分钟mi,秒s

DATEDIFF(DAY,'2024-1-1','2024-1-5') 结果:4