zoukankan      html  css  js  c++  java
  • SQL 插入语句汇总

    INSERT VALUES

    插入一行或多行到目标表中

    -- single row
    INSERT INTO Sales.MyOrders(custid, empid, orderdate, shipcountry, freight)
      VALUES(2, 19, '20120620', N'USA', 30.00);
    
    -- relying on defaults
    INSERT INTO Sales.MyOrders(custid, empid, shipcountry, freight)
      VALUES(3, 11, N'USA', 10.00);
    
    INSERT INTO Sales.MyOrders(custid, empid, orderdate, shipcountry, freight)
      VALUES(3, 17, DEFAULT, N'USA', 30.00);
    
    -- multiple rows
    INSERT INTO Sales.MyOrders(custid, empid, orderdate, shipcountry, freight) VALUES
      (2, 11, '20120620', N'USA', 50.00),
      (5, 13, '20120620', N'USA', 40.00),
      (7, 17, '20120620', N'USA', 45.00);

    注:如果要更新自增字段需要把IDENTITY_INSERT选项开启,用完后记得关闭

    SET IDENTITY_INSERT <table> ON;

    INSERT SELECT

    把select 语句的查询结果插入到表中,这个中方法要比上面的INSERT VALUES 效率高

    SET IDENTITY_INSERT Sales.MyOrders ON;
    
    INSERT INTO Sales.MyOrders(orderid, custid, empid, orderdate, shipcountry, freight)
      SELECT orderid, custid, empid, orderdate, shipcountry, freight
      FROM Sales.Orders
      WHERE shipcountry = N'Norway';
    
    SET IDENTITY_INSERT Sales.MyOrders OFF;

     

    INSERT EXEC

    该语句可以让你把动态语句或者存储过程的结果插入表格。

    -- create procedure
    IF OBJECT_ID(N'Sales.OrdersForCountry', N'P') IS NOT NULL
      DROP PROC Sales.OrdersForCountry;
    GO
    
    CREATE PROC Sales.OrdersForCountry
      @country AS NVARCHAR(15)
    AS
    
    SELECT orderid, custid, empid, orderdate, shipcountry, freight
    FROM Sales.Orders
    WHERE shipcountry = @country;
    GO
    
    -- insert the result of the procedure
    SET IDENTITY_INSERT Sales.MyOrders ON;
    
    INSERT INTO Sales.MyOrders(orderid, custid, empid, orderdate, shipcountry, freight)
      EXEC Sales.OrdersForCountry
        @country = N'Portugal';
    
    SET IDENTITY_INSERT Sales.MyOrders OFF;

    对于动态SQL,或者类似DBCC这种非常规的SQL语句,都可以通过这种方式来保存结果集。

    CREATE TABLE test_dbcc
        (
          TraceFlag VARCHAR(100) ,
          Status TINYINT ,
          Global TINYINT ,
          Session TINYINT
        )
    
    INSERT  INTO test_dbcc
            EXEC ( 'DBCC TRACESTATUS'
                )

    注:不能嵌套使用insert exec语句 ,可以用以下方式变动(这里直接拷贝参考文章中的内容。我没试验过)

    1.首先到打开服务器选项Ad Hoc Distributed Queries

    exec sp_configure 'show advanced options',1
    RECONFIGURE
    GO
    exec sp_configure 'Ad Hoc Distributed Queries',1
    RECONFIGURE
    GO

    2. 通过OPENROWSET连接到本机,运行存储过程,取得结果集

    --使用Windows认证
    SELECT  *
    INTO    #JobInfo_S1
    FROM    OPENROWSET('sqloledb', 'server=(local);trusted_connection=yes',
                       'exec msdb.dbo.sp_help_job')
    
    --使用SQL Server认证
    SELECT  *
    INTO    #JobInfo_S2
    FROM    OPENROWSET('SQLOLEDB', '127.0.0.1'; 'sa'; 'sa_password',
                       'exec msdb.dbo.sp_help_job')

    这样的写法,既免去了手动建表的麻烦,也可以避免insert exec 无法嵌套的问题。几乎所有SQL语句都可以使用。

    --dbcc不能直接运行
    SELECT  a.*
    INTO    #t
    FROM    OPENROWSET('SQLOLEDB', '127.0.0.1'; 'sa'; 'sa_password',
                       'dbcc log(''master'',3)') AS a
    
    --可以变通一下
    SELECT  a.*
    INTO    #t
    FROM    OPENROWSET('SQLOLEDB', '127.0.0.1'; 'sa'; 'sa_password',
                       'exec(''DBCC LOG(''''master'''',3)'')') AS a

    SELECT INTO

    该语句不需要我们事先建立目标表,而是直接拷贝数据源或者查询结果数据定义:比如列名,类型,是否为空,自增等来建立目标表。

    -- simple SELECT INTO
    IF OBJECT_ID(N'Sales.MyOrders', N'U') IS NOT NULL DROP TABLE Sales.MyOrders;
    
    SELECT orderid, custid, orderdate, shipcountry, freight
    INTO Sales.MyOrders
    FROM Sales.Orders
    WHERE shipcountry = N'Norway';

    通过以下存储可以查看查询返回字段的结构,注意name,system_type_name,is_nullable.

    EXEC sp_describe_first_result_set N'SELECT * FROM Sales.Customers;';

    利用select into 生成一个空表

    select * into #temp from sysobjects where 1=2

     

    实际插入案例

    1) 学生表插入

    CREATE PROCEDURE [dbo].[Students_Insert]
        (
          @ID INT ,
          @LASTNAME VARCHAR(50) ,
          @FIRSTNAME VARCHAR(50) ,
          @STATE VARCHAR(50) ,
          @PHONE VARCHAR(50) ,
          @EMAIL VARCHAR(50) ,
          @GRADYEAR INT ,
          @GPA DECIMAL(20, 10) ,
          @PROGRAM VARCHAR(50) ,
          @NEWSLETTER BIT
        )
    AS
        BEGIN
        --Check to make sure the ID does not already exist
        --If it does, return error
            DECLARE @existing AS INT = 0
            SELECT  @existing = COUNT(ID)
            FROM    Students
            WHERE   ID = @ID
        
            IF @existing > 0
                BEGIN
                    RAISERROR ('ID already exists', 1, 1)
                    RETURN 0
                END
        --Format GPA as 2 decimal places
            DECLARE @TwoDecimalGPA AS DECIMAL(3, 2)
            SELECT  @TwoDecimalGPA = CAST(@GPA AS NUMERIC(3, 2))
        --Make sure GPA is within range
            IF ( ( @TwoDecimalGPA > 4 )
                 OR ( @TwoDecimalGPA < 0 )
               )
                BEGIN
                    RAISERROR ('GPA value is invalid', 1, 1)
                    RETURN 0
                END     
        --Attempt insert
            INSERT  INTO [dbo].[Students]
                    ( [ID] ,
                      [LASTNAME] ,
                      [FIRSTNAME] ,
                      [STATE] ,
                      [PHONE] ,
                      [EMAIL] ,
                      [GRADYEAR] ,
                      [GPA] ,
                      [PROGRAM] ,
                      [NEWSLETTER]
                    )
            VALUES  ( @ID ,
                      @LASTNAME ,
                      @FIRSTNAME ,
                      @STATE ,
                      @PHONE ,
                      @EMAIL ,
                      @GRADYEAR ,
                      @TwoDecimalGPA ,
                      @PROGRAM ,
                      @NEWSLETTER
                    )
               --check to see if insert occured 
               --and return status
            IF @@ROWCOUNT = 1
                RETURN 1
            ELSE
                RETURN 0
        END
    GO

    2) 循环插入

    -----SQL SERVER中直接循环写入数据-----
    DECLARE @i INT
    SET @i = 1
    WHILE @i < 30
        BEGIN
            INSERT  INTO test
                    ( userid )
            VALUES  ( @i )
            SET @i = @i + 1
        END
    --案例:
    --有如下表,要求就裱中所有沒有及格的成績,在每次增長0.1的基礎上,使他們剛好及格:
    --    Name     score
    --    Zhangshan   80
    --    Lishi       59
    --    Wangwu      50
    --    Songquan    69
    
    WHILE ( ( SELECT    MIN(score)
              FROM      tb_table
            ) < 60 )
        BEGIN
            UPDATE  tb_table
            SET     score = score * 1.01
            WHERE   score < 60
            IF ( SELECT MIN(score)
                 FROM   tb_table
               ) > 60
                BREAK
            ELSE
                CONTINUE
        END

    参考文档

    The Data Loading Performance Guide http://msdn.microsoft.com/en-us/library/dd425070.aspx.

    01. 把存储过程结果集SELECT INTO到临时表 http://www.cnblogs.com/seusoftware/p/3222564.html

  • 相关阅读:
    Qt Qwt之坐标轴移动
    Lnux 16.04 VM下安装与汉化
    【学习笔记】开源日志记录工具log4j使用方法
    【学习笔记】关于DOM4J:使用DOM4J解析XML文档
    DOM的概念和简单应用:使用DOM解析XML数据
    初识Socket通信:基于TCP和UDP协议学习网络编程
    java 中的Scanner
    跟着前辈学编程
    集合应用案例:编写程序实现学生信息管理系统的录入登录
    简单Java程序向实用程序的过度:二进制文件的读写
  • 原文地址:https://www.cnblogs.com/haseo/p/4322249.html
Copyright © 2011-2022 走看看