• 实例TSQL 杂项(你会获益良多的)


    7、链接服务器, OPENROWSET函数


    /**//***************************************
    功能:        如何查询远程服务器对象。
    作者:       
    创建时间:    2007-08-01
    修改时间:    2007-08-01
    备注:
    引用;        关键字:链接服务器, OPENROWSET函数
    ****************************************/
    --方法一:使用链接服务器,固定.
    USE [master]
    GO
    DECLARE @SqlServer VARCHAR(50)
    SET @SqlServer=N'IpAddress'
    EXEC master.dbo.sp_addlinkedserver @server = N'LINK_TEST', @srvproduct=@SqlServer,
    @provider=N'SQLOLEDB', @datasrc=@SqlServer, @provstr=N'UID=login;PWD=password;'
    EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname=N'LINK_TEST',@useself=N'False',@locallogin=N'sa',@rmtuser=N'login',@rmtpassword='password'
    EXEC master.dbo.sp_serveroption @server=N'LINK_TEST', @optname=N'rpc', @optvalue=N'true'
    EXEC master.dbo.sp_serveroption @server=N'LINK_TEST', @optname=N'rpc out', @optvalue=N'true'
    --EXEC master.dbo.sp_dropserver @server = 'server',@droplogins = 'droplogins'
    SELECT TOP 1 * FROM link_test.logincard.dbo.zldept --测试查询

    --修改链接服务器表中的列,需指定链接名称.
    EXEC ('ALTER TABLE YourDBName.dbo.TableA ADD Field varchar(5);') at YourLinkServerName


    --方法二:使用OPENROWSET函数替代(临时性)
    -- SQL Login 
    SELECT TOP 1 a.* FROM OPENROWSET('SQLOLEDB','ipAddress';'Login';'password',Northwind.dbo.orders )a
    -- Integrierte Sicherheit 
    SELECT * FROM OPENROWSET('SQLOLEDB',  
      'Server=ipaddress;database=dbname;TRUSTED_CONNECTION=YES;',  
      'SELECT top 1 * FROM txcard.dbo.zldept') 

    --或使用 OPENDATASOURCE 连接方式
    -- Integrierte Sicherheit 
    SELECT TOP 1 * FROM OPENDATASOURCE('SQLOLEDB',  
     'Data Source=192.168.117.20;Initial Catalog=txcard;Integrated Security=SSPI;').Northwind.dbo.orders 
    -- SQL Login 
    SELECT * FROM OPENDATASOURCE('SQLOLEDB',  
    'Data Source=itrainbo2000;Initial Catalog=Northwind;User ID=student;Password=#student#;').Northwind.dbo.orders 

    更多导入导出数据查看: http://blog.csdn.net/zhou__zhou/archive/2007/06/08/1644638.aspx

    6、对一个值取反,如性别男=1,女=0,实现方式,可以使用case when ...,以下救命使用异或^


    5、在SQL2005中,如何强制删除扩展存储过程xp_cmdshell

    -- 1. 得到 master 库的目录位置(记下这个目录)
    SELECT
        LEFT(physical_name, LEN(physical_name) - 10)
    FROM master.sys.database_files
    WHERE type = 0
    -- 2. 操作系统中打开上述目录,找到如下两个文件
    mssqlsystemresource.mdf
    mssqlsystemresource.ldf
    将他们复制一份,改名为:
    _mssqlsystemresource.mdf
    _mssqlsystemresource.ldf
    -- 3. 回到 sql server, 执行下面的语句(语句中的目录要改成步骤1中查到的目录)
    USE master
    -- 将下面的文件目录修改为你自己的
    CREATE DATABASE _sys_resource
    ON(
        FILENAME = N'D:Program FilesMicrosoft SQL ServerMSSQL.1MSSQLData_mssqlsystemresource.mdf'
    )
    LOG ON(
        FILENAME = N'D:Program FilesMicrosoft SQL ServerMSSQL.1MSSQLData_mssqlsystemresource.ldf'
    )
    FOR ATTACH
    GO
    USE _sys_resource
    DROP PROC sys.xp_cmdshell
    GO
    EXEC sp_detach_db N'_sys_resource'
    -- 要重启 sql 才生效,下面这句让 sql 停止
    SHUTDOWN
    GO
    -- 4. 回到步骤 2 的目录,将下面两个文件改名以做备份
    mssqlsystemresource.mdf
    mssqlsystemresource.ldf
    -- 5. 将下面两个文件改名,去掉前面的 _
    _mssqlsystemresource.mdf
    _mssqlsystemresource.ldf
    -- 6. 重新启动 sql server, 再执行 xp_cmdshell, 你会发现找不到这个存储过程了
    1、为什么UNION ALL比UNION更快
      解:你如果还记得,union操作是将两个数据集合并在一起。它不会产生 重复或者多余的行。为了完成这样的效果,需要对这两张表执行SORT操作。这个SORT操作明显是计算密集的,并且会使用大量的内存。相反,UNION ALL仅仅是将两个集合的数据任意的合并在一起,而不管行是否重复。

    2、INTERSECT和UNION的区别?
        答:intersect是两个查询都有的非重复值(交集), union是两个查询结果的所有不重复值(并集)

    3、如何将存储过程结果插入到临时表。


    DECLARE @path VARCHAR(1000)
    SET @path='c:\'               
    DECLARE @a TABLE(str0 VARCHAR(100))
    INSERT INTO @a(str0) EXEC xp_subdirs 'c:\'
    SELECT * FROM @a WHERE ISDATE(str0)=1
    技巧:需要先知道存储过程返回的表结果结构,并预先创建相同的临时表结果。

    4、SQL中的GUEST用户有什么用的?
    guest 用户帐户允许没有用户帐户的登录访问数据库。当满足下列所有条件时,登录采用 guest 用户的标识: 
    1)登录有访问 Microsoft® SQL Server™ 实例的权限,但没有通过自己的用户帐户访问数据库的权限。
    2)数据库中含有 guest 用户帐户。 
    可以将权限应用到 guest 用户,就如同它是任何其它用户帐户一样。可以在除 master 和 tempdb 外(在这两个数据库中它必须始终存在)的所有数据库中添加或删除 guest 用户。默认情况下,新建的数据库中没有 guest 用户帐户。 

    例如,若要将 guest 用户帐户添加到名为 Accounts 的数据库中,请在 SQL 查询分析器中运行下列代码:
    USE Accounts
    GO
    EXECUTE sp_grantdbaccess guest

    13--计算员工最近的生日的日期. 以Northwind数据库为例.
    SELECT firstname,lastname,BirthDate,CASE WHEN DATEADD(yy,DATEDIFF(yy,BirthDate,GETDATE()),BirthDate)<=getdate() THEN DATEADD(yy,DATEDIFF(yy,BirthDate,GETDATE()),BirthDate) ELSE DATEADD(yy,DATEDIFF(yy,BirthDate,GETDATE())-1,BirthDate)END [最近一次生日] FROM Employees
    --思路: 需要先得到今年的生日日期,如果获取的生日日期大于当前日期,就获取最近一次的生日日期(去年的生日日期,谁让生日一年一次呢.),如果小于等于当前日期,那这次就是最近的生日日期了.
    --注意: 因为闰年的关系,二月的生日可能会在差异.

    12、按汉字笔画排序
    SELECT  * FROM [YouTable]
    ORDER BY [字段] COLLATE Chinese_PRC_Stroke_CI_AS_KS
    11,从这一示例了解解决问题的新想法.
    /**//*有一成绩表,数据如下:
    Name       Course     Mark
    ---------- ---------- ----------------------
    李四         数学         90
    李四         语文         76
    王五         英语         100
    王五         语文         81
    张三         数学         75
    张三         语文         81
    需求:查询出每门课都大于80分的学生姓名
    结果:王五
    */
    -- 方式一: not exists
    SELECT name FROM @test a WHERE NOT EXISTS (SELECT 1 FROM @test WHERE a.Course=Course AND mark<80)
    -- 另一个思路
    SELECT NAME FROM @test GROUP BY name HAVING count(*)=sum(case when mark>=80 then 1 else 0 end)
    10,全角半角转换函数. CREATE FUNCTION dbo.ufnConvert( 
      @str NVARCHAR(4000),        --要转换的字符串 
      @flag bit                    --转换标志,0转换成半角,1转换成全角 
    )RETURNS   NVARCHAR(4000) 
    /**//*******************************
    函数功能:    半角全角转换函数.
    创建日期:    2007-09-28
    使用示例:   
      declare   @s1   varchar(8000) 
      select   @s1='中    2-3456a78STUVabn中国opwxyz' 
      select   dbo.ufnconvert(@s1,0),dbo.ufnconvert(@s1,1)  
    引用:        网摘.
    */
    AS 
    BEGIN 
    DECLARE @pat nvarchar(8),@step int,@i int,@spc int 
      IF @flag=0 
      SELECT @pat=N'%[!-~]%',@step=-65248, 
      @str=REPLACE(@str,N' ',N'   ') 
      ELSE 
      SELECT @pat=N'%[!-~]%',@step=65248, 
      @str=REPLACE(@str,N'   ',N' ') 
      SET @i=PATINDEX(@pat   COLLATE   LATIN1_GENERAL_BIN,@str) 
      WHILE @i>0 
      SELECT @str=REPLACE(@str, SUBSTRING(@str,@i,1), NCHAR(UNICODE(SUBSTRING(@str,@i,1))+@step)),@i=PATINDEX(@pat COLLATE LATIN1_GENERAL_BIN,@str) 
      RETURN(@str) 
    END 
    GO 
    --结果:
    半角                                                                                全角
    中      2-3456,,,,,a78S,TUVabn中国opwxyz    中  2-3456,,,,,a78S,TUVabn中国opwxyz
    9、删除A表中只有id不同的相同记录。条件,保留id最大的记录。
    DECLARE @t TABLE(id INT ,str1 VARCHAR(10),str2 VARCHAR(10),str3 VARCHAR(10))
    INSERT INTO @t
    SELECT 1,'11','22','33'
    UNION
    SELECT 3,'11','22','33'
    UNION
    SELECT 2,'11','22','33'
    UNION
    SELECT 4,'11','22','33'
    --NOT EXISTS
    SELECT * FROM @t a WHERE NOT EXISTS(SELECT id FROM @t WHERE a.id<id AND str1=a.[str1])
    --NOT IN
    SELECT * FROM @t where id NOT in
    (select a.id from @t a, @t b
    where a.str1 = b.str1 and a.ID < b.ID)
    8、删除A表中B表不存在的记录
    delete from a where not exists ( select * from b where a.Keyid=b.Keyid )
    7、如何用SQL语句创建一个自动编号的字段
    CREATE TABLE mytable(obj_id INT IDENTITY(1,1) NOT NULL)
    6、重新生成ID增值列(以旧的ID列为条件)
    select id,(id-(select min(id) from a)+1) as new_id from a
    5、随机排序表查询结果。使用newid()函数
    这种方法是要对整个表扫描,然后产生一个计算列再排序的,最好百万记录表作这样的操作,否则会很慢的。
    SELECT * FROM Table ORDER BY NEWID()

    4、检验数据库是否存在并做进一步操作。其它对象可举一反三,
    比如表:IF object_id('[dbo].[Table]','U') IS NOT NULL
    IF DB_ID(N'DBName')IS NOT NULL
    PRINT 'DB exists'
    ELSE
    PRINT 'DB not exists'或: IF EXISTS (select * from master..sysdatabases where name = 'DBName)
    PRINT 'DB exists'
    ELSE
    PRINT 'DB not exists'
    3、删除表中的所有记录后,标识还是从1开始
    --方法1:
    truncate Table YourTable --這樣不但將數據刪除,而且可以重新置位identity屬性的字段。

    --方法2:
    Delete From YourTable
    dbcc checkident(YourTable,reseed,0) --重新置位identity屬性的字段,讓其下個值從1開始

    2、查看表结构
    EXEC sp_mshelpcolumns  'object_Name'更多参考未公开存储过程

    1、重命名列:
    sp_rename 'a表.列名b','列名改为C','column' 更多参考联机帮助:更改用户创建对象的名称 sp_rename

    0、为数据库表设计时选择最合理的数据类型。
    例需求如下:定义一个新表来跟踪用户从在线商店购买商品的行为。要为每个列考虑合适的名字、数据类型、以及可空性选项。由于对存储有严格需求,所以尽量使用保守的数据类型。以下是表的设计准则:

    * 定义1个单一列作为顾客的名字。允许1到200个字符且必须填写,一些顾客可能使用外国名。
    * 需要4个列来保存顾客的地址、城市、州与邮政编码。所有的地址与城市只包含美国本土名字,而且这些列中没有一个是必须要有值的。地址列应该允许最多保存200个字符,城市应该保存100个字符,州永远是一个2字节的缩写,而邮政编码长度总是5个字节的。
    * 需要1个列来保存商品的购买数量,这个列将保存整数值,最大为10 000,而且必须将新记录自动设置为1。
    * 需要1个列来存储所支付的金额,这是必须要填写的字段。存储的值最高为$100 000.
    我的需求分析:虽然习惯上认为应该要定义主键列,但需求并没有指定这一点。CustomerName列被定义为nvarchar类型的,这样就可以使用国际字符集储存Unicode字符了。虽然这样做将会使得存储需求加倍,但是却最可能高的效率符合了需求。
    Address0 与City列不需要Unicode能力,所以它们使用 varchar 数据类型。State列使用固定长度的类型,这是因为与varchar类型有关的开销至少是2字节,即使这个列是空值。ZipCode列要么定义为 char(5),要么定义为varchar(5)类型,使用char类型保存小一点的值可以稍微提升性能,不过即使是空值,char也要占用5个字节的存 储空间。虽然在这个例子中使用char类型可能更实际一些,但需求要求我们减少存储空间。SmallMoney类型虽然并不常用,不过它能减少存储空间, 并且满足最大值的需要。所以题解如下:


    CREATE TABLE MyTable(CustomerName nVARCHAR(200) NOT NULL
                        ,Address0 VARCHAR(200) NULL
                        ,City VARCHAR(100) NULL
                        ,State0 CHAR(2) NULL
                        ,ZipCode VARCHAR(5)
                        ,Quantity INT NOT NULL DEFAULT 1
                        ,Price SmallMoney NOT NULL
                        ,CONSTRAINT ck_state0 CHECK (state0 IN ('WA','OR'))
                        ,CONSTRAINT ck_Quantity CHECK (Quantity BETWEEN 1 AND 10000)
                        ,CONSTRAINT ck_price CHECK (price BETWEEN $0 AND $100000))

    DECLARE @tb TABLE (sex INT ,num2 INT)
    INSERT INTO @tb SELECT 1,9
    INSERT INTO @tb SELECT 0,0
    INSERT INTO @tb SELECT 0,1
    INSERT INTO @tb SELECT 1,9
    INSERT INTO @tb SELECT 0,1
    INSERT INTO @tb SELECT 1,1
    INSERT INTO @tb SELECT 0,9
    INSERT INTO @tb SELECT 1,1
    INSERT INTO @tb SELECT 0,9
    INSERT INTO @tb SELECT 1,1

    SELECT sex,sex取反=sex^1,num2,num2取反=num2^9 FROM @tb

    本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/zhou__zhou/archive/2007/07/24/1705545.aspx

  • 相关阅读:
    Java多线程同步和异步问题
    最优二叉查找树
    岛屿的周长
    Mac 环境下 go 国内代理配置
    岛屿数量
    字符串解码
    环形链表 II
    颜色分类
    无重复字符的最长子串
    完全平方数
  • 原文地址:https://www.cnblogs.com/0000/p/1516297.html
Copyright © 2020-2023  润新知