记录使用SQL Server过程中学到的小知识点

A-1. SQL Server获取自增列下一个Id


IDENT_CURRENT('TableName')为当前的最大标识值,IDENT_INCR('TableName')为设置的标识值增量, 两者相加即为下一个标识值

SELECT IDENT_CURRENT('TableName') + IDENT_INCR('TableName');

参考链接:https://social.microsoft.com/Forums/zh-CN/07c3a188-5ae1-4623-ba14-0ae2148f5be0/sql-server-id
SQL Docs: https://docs.microsoft.com/en-us/sql/t-sql/functions/data-type-functions-transact-sql

A-2. 去掉字符串中的最后一个字符


A-2.1 使用LEFT/SUBSTRING/STUFF(Ref-1Ref-2)函数

DECLARE @String as VARCHAR(50)
SET @String = '1,2,3,4,5,6,7,8,9,10,'

--使用LEFT函数及LEN/DATALENGTH函数
SELECT @String AS [String], LEFT(@String, LEN(@String) - 1) AS [Substing Without Last Character]
SELECT @String AS [String], LEFT(@String, DATALENGTH(@String) - 1) AS [Substing Without Last Character]

--使用SUBSTRING函数
SELECT @String As [String], SUBSTRING(@String, 1, LEN(@String) - 1) AS [Substing Without Last Character]

--使用STUFF函数
SELECT @String AS [String], STUFF(@String, LEN(@String), 1, '') AS [Substing Without Last Character]


A-2.2 用于实战中的写法: 字符串可能为null或空串

--使用NULLIF(Ref-1)表达式检查
SELECT @String AS [String], LEFT(@String, NULLIF(LEN(@String) - 1, -1)) AS [Substing Without Last Character]

--使用CASE表达式检查
SELECT @String As [String],
     CASE @String WHEN null THEN null 
     ELSE (
         CASE LEN(@String) WHEN 0 THEN @String 
            ELSE LEFT(@String, LEN(@String) - 1) 
         END 
     ) END AS [Substing Without Last Character]

参考链接:https://stackoverflow.com/questions/1256915/remove-the-last-character-in-a-string-in-t-sql

A-3. CASE-WHEN的一些巧妙用法

A-3.1 巧用CASE-WHEN同时验证用户帐号是否存在、密码是否正确


DECLARE @un as NVARCHAR(50)
DECLARE @pwd as Nvarchar(100)
SET @un  = 'admin'
SET @pwd = '12345678'

SELECT
    CASE WHEN [Pwd]= @pwd THEN 1 ELSE 0 END AS [IsExist]
FROM [User]
WHERE [LoginName] = @un

简单解释:

  • 如果用户名不存在,则查询结果是无数据.
  • 如果用户名存在但密码不正确,则查询结果是 0.
  • 如果用户名存在且密码正确,则查询结果是 1.

 

A-3.2  在CASE-WHEN中使用IN

SELECT Id,
  CASE WHEN Id IN ('2', '4') THEN 1 ELSE 0 END AS Even 
FROM (Values('1'), ('2'), ('3'), ('4'), ('5')) temp (Id)

 

A-3.3  巧用CASE-WHEN动态调整排序项

SELECT * FROM TableName
ORDER BY CASE WHEN COL1 > 100 THEN COL1 ELSE COL2 END

 

A-4. 随机返回若干行记录

SELECT TOP (5) * FROM TableName ORDER BY NEWID()

 

A-5. WHERE子句中通过派生表使用别名

/** 使用派生表 **/
SELECT * FROM
  (
    SELECT 
      order_num, 
      COUNT(order_num) AS SUM
    FROM [OrderItems]
    GROUP BY order_num
  ) AS ORDERS
WHERE SUM > 4

/** 使用Having子句 **/
SELECT 
  order_num, 
  COUNT(order_num) AS SUM
FROM [OrderItems]
GROUP BY order_num
HAVING COUNT(order_num) > 4

 

A-6. 复制表定义及数据

--复制表定义
SELECT * INTO [TableName2] FROM [TableName1] WHERE 1 = 0

--复制表数据到另一张表(可以添加Where子句)
INSERT INTO [TableName2] SELECT * FROM [TableName1]

--复制表定义及数据(可以添加Where子句)
SELECT * INTO [TableName2] FROM [TableName1]

 

A-7. 执行由字符串拼接而成的SQL语句



DECLARE @sqlText nvarchar(max) 
DECLARE @tableName varchar(100)
SET @tableName= 'Employee'

--查询某张表中可以为null的列
SET @sqlText = N'select * from sys.columns where object_id = object_id('''+ @tableName +''') and is_nullable = 1'
Exec (@sqlText)

 

B-1. 列举数据库中的表名, 列名, 列的数据类型及是否可以为null等


SELECT 
     TABLE_CATALOG
    ,TABLE_SCHEMA
    ,TABLE_NAME
    ,COLUMN_NAME
    ,DATA_TYPE
    ,IS_NULLABLE
    ,COLUMN_DEFAULT
FROM INFORMATION_SCHEMA.COLUMNS --系统视图
WHERE TABLE_SCHEMA = 'dbo' --以下过滤条件根据自身需求取设定 AND TABLE_NAME = 'TableName' AND COLUMN_NAME = 'ColumnName' ORDER BY TABLE_NAME

 

B-2. 查询数据库中所有含有字段名为"ColumnName"的表


SELECT 
  a.[Name] AS TableName, 
  b.[Name] AS ColumnName
FROM sysobjects a 
  INNER JOIN syscolumns b ON a.id = b.id
WHERE
  b.Name in ('ColumnName') 
ORDER BY a.Name

 

B-3. 查询数据库中所有表的约束及对应字段


SELECT
    tb.TABLE_CATALOG, 
    tb.TABLE_SCHEMA, 
    tb.TABLE_NAME, 
    tc.CONSTRAINT_TYPE, 
    tc.CONSTRAINT_NAME, 
    kc.COLUMN_NAME, 
    col.IS_NULLABLE,
    col.DATA_TYPE,
    CASE DATA_TYPE
        WHEN 'bit'            THEN cast(col.NUMERIC_PRECISION_RADIX as varchar)
        WHEN 'tinyint'        THEN cast(col.NUMERIC_PRECISION_RADIX as varchar)
        WHEN 'smallint'       THEN cast(col.NUMERIC_PRECISION_RADIX as varchar)
        WHEN 'int'            THEN cast(col.NUMERIC_PRECISION_RADIX as varchar) 
        WHEN 'bigint'         THEN cast(col.NUMERIC_PRECISION_RADIX as varchar)
        WHEN 'real'           THEN cast(col.NUMERIC_PRECISION as varchar) + ',' + cast(col.NUMERIC_SCALE as varchar)
        WHEN 'float'          THEN cast(col.NUMERIC_PRECISION as varchar) + ',' + cast(col.NUMERIC_SCALE as varchar)
        WHEN 'money'          THEN cast(col.NUMERIC_PRECISION as varchar) + ',' + cast(col.NUMERIC_SCALE as varchar)
        WHEN 'smallmoney'     THEN cast(col.NUMERIC_PRECISION as varchar) + ',' + cast(col.NUMERIC_SCALE as varchar)
        WHEN 'decimal'        THEN cast(col.NUMERIC_PRECISION as varchar) + ',' + cast(col.NUMERIC_SCALE as varchar)
        WHEN 'numeric'        THEN cast(col.NUMERIC_PRECISION as varchar) + ',' + cast(col.NUMERIC_SCALE as varchar)
        WHEN 'date'           THEN cast(col.DATETIME_PRECISION as varchar)
        WHEN 'time'           THEN cast(col.DATETIME_PRECISION as varchar)
        WHEN 'smalldatetime'  THEN cast(col.DATETIME_PRECISION as varchar)
        WHEN 'datetime'       THEN cast(col.DATETIME_PRECISION as varchar)
        WHEN 'datetime2'      THEN cast(col.DATETIME_PRECISION as varchar)
        WHEN 'datetimeoffset' THEN cast(col.DATETIME_PRECISION as varchar)
        ELSE                       cast(col.CHARACTER_MAXIMUM_LENGTH as varchar) 
    END AS MAX_LENGTH_OR_PRECISION,
    kc.ORDINAL_POSITION,
    rc.UNIQUE_CONSTRAINT_NAME
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc 
    RIGHT JOIN INFORMATION_SCHEMA.TABLES tb ON tc.TABLE_NAME = tb.TABLE_NAME
    JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE kc ON tc.CONSTRAINT_NAME = kc.CONSTRAINT_NAME
    JOIN INFORMATION_SCHEMA.COLUMNS col ON col.COLUMN_NAME = kc.COLUMN_NAME 
        AND col.TABLE_NAME = kc.TABLE_NAME 
        AND col.TABLE_SCHEMA = kc.TABLE_SCHEMA
    LEFT JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc ON tc.CONSTRAINT_NAME = rc.CONSTRAINT_NAME
ORDER BY tc.TABLE_NAME, kc.COLUMN_NAME
posted @ 2016-07-06 20:37  天琊蓝  阅读(2891)  评论(1编辑  收藏  举报