SQL Server常见基础操作

1. 常见针对表的操作(增删改查)

--1. Create Table
USE [MVC_000]
CREATE TABLE T_TableName
(  
    ID INT IDENTITY(1,1) PRIMARY KEY,
    Name VARCHAR(50) UNIQUE,  
    Age INT,
    HomeAddress VARCHAR(50)
)  

--2. Insert data into table:T_TableName
INSERT INTO T_TableName(Name,Age,HomeAddress) 
VALUES('Xiao Lin',29,'SD.Road New York')

--3. Truncate table
IF OBJECT_ID(N'T_TableName',N'U') IS NOT NULL
BEGIN
    TRUNCATE TABLE T_TableName
END

--4. Delete record
IF EXISTS(SELECT * FROM T_TableName WHERE ID=1)
BEGIN
    DELETE T_TableName WHERE ID=1
END

--5. Drop table
IF OBJECT_ID(N'T_TableName',N'U') IS NOT NULL
BEGIN
    DROP TABLE T_TableName
END
View Code

2. 临时表,表变量及CTE(公用表表达式)的操作

临时表存在于tempdb中,全局临时表以”##“开头。临时表需要手动清除,而CTE和表变量使用完成后会自动清除。

--1. Temporary table
    --A. Check and delete if current temporary table is exists
    IF OBJECT_ID('TEMPDB..#TempTable') IS NOT NULL
    BEGIN
        DROP TABLE #TempTable
    END
    CREATE TABLE #TempTable
    (
        ID BIGINT,   
        FIRST_NAME VARCHAR(50),    
        LAST_NAME VARCHAR(50),    
        PASSPORT VARCHAR(50),    
        GENDER VARCHAR(50),    
        BIRTH_DATE DATE,    
        STATUS CHAR(1)
    )
    --Insert data
    INSERT INTO TABLE #TempTable
    SELECT ID,FIRST_NAME,LAST_NAME,PASSPORT,GENDER,BIRTH_DATE,STATUS FROM TableName
    --Search
    SELECT * FROM #TempTable

    --B. Or you can use it without definition
    --Insert data
    INSERT INTO TABLE #TempTable
    SELECT ID,FIRST_NAME,LAST_NAME,PASSPORT,GENDER,BIRTH_DATE,STATUS FROM TableName
    --Search
    SELECT * FROM #TempTable

--2. Define table variables 
    --For definine
    DECLARE @TempTable TABLE    
    (    
        ID BIGINT,   
        FIRST_NAME VARCHAR(50),    
        LAST_NAME VARCHAR(50),    
        PASSPORT VARCHAR(50),    
        GENDER VARCHAR(50),    
        BIRTH_DATE DATE,    
        STATUS CHAR(1)
    )
    --Insert data
    INSERT INTO TABLE @TempTable
    SELECT ID,FIRST_NAME,LAST_NAME,PASSPORT,GENDER,BIRTH_DATE,STATUS FROM TableName
    --Search
    SELECT * FROM @TempTable

--3. CTE(Common Table Expression)
    ;WITH TestTable AS
    (
        SELECT * FROM [dbo].[TbEmployee] WHERE EmployeeId>10
    )

    SELECT * FROM TestTable
View Code

3. 游标操作

USE [DB_NAME]

DECLARE CSR_NAME CURSOR FOR
SELECT Column1,Column2 FROM [dbo].[XXX]
    
DECLARE @Column1 INT
DECLARE @Column2 INT

OPEN CSR_NAME
FETCH NEXT FROM CSR_NAME INTO @Column1, @Column2
WHILE @@FETCH_STATUS = 0
BEGIN
        
    IF @Column1>3
    BEGIN
        PRINT('First column is bigger than 3!')
    END
    ELSE IF @Column1=3
    BEGIN
        PRINT('First column is equals 3!')
    END
    ELSE
    BEGIN
        PRINT('First column is less than 3!')
    END
    FETCH NEXT FROM CSR_NAME INTO @Column1, @Column2
END
CLOSE CSR_NAME
DEALLOCATE CSR_NAME
View Code

4. 存储过程模板

USE DBName
GO
IF EXISTS ( SELECT * FROM sys.objects WHERE [Name] = 'SP_NAME' AND [Type]  = 'P' )
BEGIN
    DROP PROCEDURE dbo.SP_NAME
    PRINT @@SERVERNAME + ' - ' + CONVERT ( varchar, GETDATE(), 121 ) + ' : ### ' + DB_NAME() + '.dbo.SP_NAME - dropped'
END
GO
/************************************************************************************************************
    Work Request:   ProjectName
    Module Name:    ModuleName
    Object Name:    DB_NAME
    Description:    
    Parameters:     @XXX1 INT
                         @XXX2 INT
    Returns:        None
**************************************************************************************************************
    Version Control:
    Date          Version    Author         WR#                        Description
    2020-06-10  1.0         Name          ProjectName              Create
*************************************************************************************************************
    Unit Test:
    EXEC dbo.SP_NAME 1,2
*************************************************************************************************************/
USE [DB_NAME]
CREATE PROC [dbo].[SP_NAME]
--Declare
@XXX1 INT,
@XXX2 INT
AS

SELECT * FROM dbo.XXX WHERE XXX1=@XXX1 AND XXX2=@XXX2
GO
View Code

5. 函数模板

 表值函数:

--Create
USE [DB_NAME]
CREATE FUNCTION BZ_FUNCTION(@Type VARCHAR(1))
RETURNS @AllInfor TABLE (ID INT,NAME VARCHAR(50))
AS

BEGIN
    IF(@Type='A')
    BEGIN
        INSERT @AllInfor VALUES (1,'LI LEI')
    END
    ELSE
    BEGIN
        INSERT @AllInfor VALUES (2,'HAN MEIMEI')
    END
    RETURN
END

--Usage
SELECT * FROM BZ_FUNCTION('A')
View Code

内嵌表值函数(实质也是表值函数):

CREATE FUNCTION IF_GetStudentList(@ClassName VARCHAR(10))
RETURNS TABLE
AS
RETURN (SELECT * FROM Students WHERE ClassName LIKE '%'+@ClassName+'%')
--For Testing:SELECT * FROM IF_GetStudentList(1)
View Code

标量值函数:

--Create
USE [DB_NAME]
CREATE FUNCTION BLZ_FUNCTION(@Type VARCHAR(50))
RETURNS VARCHAR(20)
AS

BEGIN
    DECLARE @Result VARCHAR(20)
    IF(LEN(@Type)>=8)
    BEGIN
        SET @Result='SUCCESSFULL!'
    END
    ELSE
    BEGIN
        SET @Result='Failed!'
    END
    RETURN @Result
END

--Usage
SELECT dbo.BLZ_FUNCTION(XXX.ColumnName) FROM [dbo].[XXX]
View Code

为什么只有内嵌表值函数而没有内嵌标量值函数:
表值函数返回一个表的数据,内嵌表值函数可以通过传入不同的参数获取不同的返回值列表;
而标量值返回的是一个值,已经无法对返回结果进行拆分,所以内嵌标量值函数没有任何意义;

6. 触发器模板

 Instead Of:

 在对数据做DML操作之前,需要对数据进行验证,如果验证失败,则该操作会被取消(这应该就是Instead of的具体体现了吧)。

--Instead of means that the actual statement will be replaced by the trigger,so the actual statement will not be executed.
--[Instead trigger] will be executed after the execution of actual statement.
IF (OBJECT_ID('TRG_STU_INSTEADOF', 'TR') IS NOT NULL)
BEGIN
    DROP TRIGGER TRG_STU_INSTEADOF
END
GO

CREATE TRIGGER TRG_STU_INSTEADOF
ON [dbo].[Students]
    INSTEAD OF DELETE 
AS
    DECLARE @ID INT,@StuName VARCHAR(20)
    SELECT @ID=StudentID,@StuName=StudentName FROM deleted
    PRINT 'The delete of students information[ID:'+CONVERT(VARCHAR,@ID)+';Name:'+@StuName+'] is successful!';
GO
View Code

 After:

--By default,the type of trigger is after.(DML)
--[After trigger] will be executed after the execution of actual statement.
IF (OBJECT_ID('TRG_STU', 'TR') IS NOT NULL)
BEGIN
    DROP TRIGGER TRG_STU
END
GO
CREATE TRIGGER TRG_STU
ON [dbo].[Students]
    FOR INSERT 
AS
    DECLARE @ID INT,@StuName VARCHAR(20)
    SELECT @ID=StudentID,@StuName=StudentName FROM inserted
    PRINT 'The adding for students information[ID:'+CONVERT(VARCHAR,@ID)+';Name:'+@StuName+'] is successful!';
GO
View Code

7. 常见脚本

  A. 循环写入测试数据

DECLARE @ID INT=0
WHILE @ID<40000
BEGIN
INSERT INTO CCTV VALUES ('Johnson','How to insert test data to our DB?',GETDATE(),GETDATE(),0)
SELECT @ID=MAX(ID) FROM CCTV
END
View Code

  B. 评估SQL的执行时间

USE DBName
DECLARE @StartTime DateTime,
        @EndTime   DateTime
SET @StartTime=GetDate()
    --Your scripts
SET @EndTime=GetDate()
PRINT('Total '+CONVERT(VARCHAR,DATEDIFF(millisecond,@StartTime,@EndTime)) +' milliseconds were used!');
View Code

  c. 根据一个表更新另一个表的值

UPDATE TB1 
SET TB1.TB1_Name=TB2.TB2_Name
FROM dbo.TB1 
LEFT JOIN dbo.TB2 ON TB1.ID=TB2.ID
WHERE TB1_Name IS NULL
View Code

8 . 系统表操作

系统表SYSOBJECTS中的列XTYPE所代表的类型:

--C:Check约束
--D:Default约束
--PK:PRIMARY KEY约束
--F:FOREIGN KEY约束
--UQ:UNIQUE约束

--L:LOG

--S:SYSTEM TABLES
--U:User TABLES
--V:View
--P:Procedure
--TF:表值函数
  --IF:内嵌表值函数(在一个函数内部嵌入一个表值函数,也属于表值函数)
--FN:标量值函数
--TR:Trigger

--X:Extension Procedure
--RF:复制筛选存储过程
View Code

常见用法:

--查询一个表用到的所有触发器:
SELECT * FROM SYSOBJECTS WHERE xtype='TR' AND parent_obj=OBJECT_ID('Table_Name')

--查询一个表中所有的列名
SELECT NAME FROM SYSCOLUMNS WHERE ID=OBJECT_ID('Table_Name')

--查询一个表中所有的列名及数据类型
SELECT A.Name AS ColumnNAME,B.Name AS DataType FROM SYSCOLUMNS A 
LEFT JOIN SYSTYPES B ON A.XTYPE=B.xtype WHERE A.ID=OBJECT_ID('Table_Name')

--查询一个表中所有的列名及数据类型(包含表的类型)
SELECT A.Name AS FieldName,B.Type_Desc,B.Type,C.Name AS TypeName FROM SYS.COLUMNS A
LEFT JOIN SYS.OBJECTS B ON A.object_id=B.object_id
LEFT JOIN SYS.TYPES C ON A.system_type_id=C.system_type_id
WHERE B.type='U' AND CHARINDEX('UDT',C.name,0)<=0 AND CHARINDEX('SYS',C.name,0)<=0 AND B.name='Table_Name'

--读取数据库对象脚本(Only For View/SP/Function/Trigger)
SP_HELPTEXT Obj_Name
View Code

 9. 其他用法

 查看SQLServer当前版本号及详细信息:select @@version

 查看当前数据库的使用用户:sp_who

 结束某个用户对当前数据库的使用:kill spid

10. 总结

A、如果在一个存储过程中A使用了临时表,如果在存储过程B中无法将获得的存储过程A的结果存入临时表,会报错;
B、函数中无法执行EXEC命令,即不能在函数中调用存储过程;
C、对于一个JOB来说,要使它能正常运行起来,除了要启用它之外,还需要注意JOB的schedule,一定要按照SQLSERVER所在的服务器的时间来进行配置;

原文地址:https://www.cnblogs.com/sccd/p/5479064.html