标签: t-sql

SQL Server 中的临时表和表变量有什么区别?

这似乎是一个有很多神话和相互冲突的领域。

那么SQL Server中的表变量和本地临时表有什么区别呢?

sql-server t-sql temporary-tables

465
推荐指数
2
解决办法
24万
查看次数

每组检索 n 行

我经常需要从结果集中的每个组中选择一些行。

例如,我可能想列出每个客户最近的“n”个最高或最低订单值。

在更复杂的情况下,要列出的行数可能因组而异(由分组/父记录的属性定义)。这部分绝对是可选的/为了额外的学分,而不是为了劝阻人们回答。

在 SQL Server 2005 及更高版本中解决这些类型问题的主要选项是什么?每种方法的主要优点和缺点是什么?

AdventureWorks 示例(为清晰起见,可选)

  1. 列出表中五个最近的交易日期和 ID TransactionHistory,每个产品以从 M 到 R 的字母开头。
  2. 再次相同,但n每个产品都有历史记录行,其中nDaysToManufactureProduct 属性的五倍。
  3. 同样,对于每个产品恰好需要一条历史记录行的特殊情况(最近的单个条目由TransactionDate, .tie-break on TransactionID.

sql-server t-sql greatest-n-per-group

97
推荐指数
6
解决办法
7万
查看次数

MERGE 目标表的一个子集

我正在尝试使用MERGE语句从表中插入或删除行,但我只想对这些行的一个子集进行操作。的文档MERGE有一个措辞非常强烈的警告:

仅指定目标表中用于匹配目的的列很重要。也就是说,指定目标表中与源表的相应列进行比较的列。不要试图通过在 ON 子句中过滤掉目标表中的行来提高查询性能,例如通过指定 AND NOT target_table.column_x = value。这样做可能会返回意外和不正确的结果。

但这正是我必须做的事情才能完成我的MERGE工作。

我拥有的数据是一个标准的项目到类别的多对多连接表(例如,哪些项目包含在哪些类别中),如下所示:

CategoryId   ItemId
==========   ======
1            1
1            2
1            3
2            1
2            3
3            5
3            6
4            5
Run Code Online (Sandbox Code Playgroud)

我需要做的是用新的项目列表有效地替换特定类别中的所有行。我最初的尝试是这样的:

MERGE INTO CategoryItem AS TARGET
USING (
  SELECT ItemId FROM SomeExternalDataSource WHERE CategoryId = 2
) AS SOURCE
ON SOURCE.ItemId = TARGET.ItemId AND TARGET.CategoryId = 2
WHEN NOT MATCHED BY TARGET THEN
    INSERT ( CategoryId, ItemId )
    VALUES ( 2, ItemId ) …
Run Code Online (Sandbox Code Playgroud)

sql-server t-sql merge

74
推荐指数
1
解决办法
8万
查看次数

使用窗口函数的日期范围滚动总和

我需要计算一个日期范围内的滚动总和。为了说明,使用AdventureWorks 示例数据库,以下假设语法将完全满足我的需要:

SELECT
    TH.ProductID,
    TH.TransactionDate,
    TH.ActualCost,
    RollingSum45 = SUM(TH.ActualCost) OVER (
        PARTITION BY TH.ProductID
        ORDER BY TH.TransactionDate
        RANGE BETWEEN 
            INTERVAL 45 DAY PRECEDING
            AND CURRENT ROW)
FROM Production.TransactionHistory AS TH
ORDER BY
    TH.ProductID,
    TH.TransactionDate,
    TH.ReferenceOrderID;
Run Code Online (Sandbox Code Playgroud)

遗憾的是,RANGE窗口框架范围目前在 SQL Server 中不允许间隔。

我知道我可以使用子查询和常规(非窗口)聚合编写解决方案:

SELECT 
    TH.ProductID,
    TH.TransactionDate,
    TH.ActualCost,
    RollingSum45 =
    (
        SELECT SUM(TH2.ActualCost)
        FROM Production.TransactionHistory AS TH2
        WHERE
            TH2.ProductID = TH.ProductID
            AND TH2.TransactionDate <= TH.TransactionDate
            AND TH2.TransactionDate >= DATEADD(DAY, -45, TH.TransactionDate)
    )
FROM Production.TransactionHistory AS TH
ORDER BY
    TH.ProductID,
    TH.TransactionDate, …
Run Code Online (Sandbox Code Playgroud)

performance sql-server t-sql sql-server-2012 window-functions query-performance

59
推荐指数
5
解决办法
5万
查看次数

在 SQL Server 中创建可以保存存储过程结果的临时表的最简单方法是什么?

很多时候我在处理 SQL Server 时需要编写如下内容。

create table #table_name
(
    column1 int,
    column2 varchar(200)
    ...
)

insert into #table_name
execute some_stored_procedure;
Run Code Online (Sandbox Code Playgroud)

但是,创建一个具有作为存储过程结果的精确语法的表是一项繁琐的任务。例如,sp_helppublication的结果有 48 列!我想知道是否有任何简单的方法可以做到这一点。

谢谢。

sql-server stored-procedures t-sql

53
推荐指数
2
解决办法
29万
查看次数

SQL Server CASE 语句是评估所有条件还是在第一个 TRUE 条件时退出?

SQL Server(特别是 2008 或 2012)CASE语句是评估所有WHEN条件还是在找到WHEN评估为真的子句后退出?如果它确实通过了整个条件集,这是否意味着最后一个条件评估为 true 会覆盖第一个评估为 true 的条件所做的事情?例如:

SELECT
    CASE
        WHEN 1+1 = 2 THEN'YES'
        WHEN 1+1 = 3 THEN 'NO'
        WHEN 1+1 = 2 THEN 'NO' 
    END
Run Code Online (Sandbox Code Playgroud)

结果是“YES”,即使最后一个 when 条件应该使它评估为“NO”。一旦找到第一个 TRUE 条件,它似乎就退出了。有人可以确认是否是这种情况

sql-server t-sql case

53
推荐指数
3
解决办法
11万
查看次数

如何创建 Unicode 参数和变量名称

所有这些都有效:

CREATE DATABASE [¯\_(?)_/¯];
GO
USE [¯\_(?)_/¯];
GO
CREATE SCHEMA [¯\_(?)_/¯];
GO
CREATE TABLE [¯\_(?)_/¯].[¯\_(?)_/¯]([¯\_(?)_/¯] NVARCHAR(20));
GO
CREATE UNIQUE CLUSTERED INDEX [¯\_(?)_/¯] ON [¯\_(?)_/¯].[¯\_(?)_/¯]([¯\_(?)_/¯]);
GO
INSERT INTO [¯\_(?)_/¯].[¯\_(?)_/¯]([¯\_(?)_/¯]) VALUES (N'[¯\_(?)_/¯]');
GO
CREATE VIEW [¯\_(?)_/¯].[vw_¯\_(?)_/¯] AS SELECT [¯\_(?)_/¯] FROM [¯\_(?)_/¯].[¯\_(?)_/¯];
GO
CREATE PROC [¯\_(?)_/¯].[sp_¯\_(?)_/¯] @Shrug NVARCHAR(20) AS SELECT [¯\_(?)_/¯] FROM [¯\_(?)_/¯].[vw_¯\_(?)_/¯] WHERE [¯\_(?)_/¯] = @Shrug;
GO
EXEC [¯\_(?)_/¯].[¯\_(?)_/¯].[sp_¯\_(?)_/¯] @Shrug = N'[¯\_(?)_/¯]';
GO
Run Code Online (Sandbox Code Playgroud)

但是您可能会看到我的意思:我不想要 @Shrug,我想要@¯\_(?)_/¯.

这些都不适用于 2008-2017 的任何版本:

CREATE PROC [¯\_(?)_/¯].[sp_¯\_(?)_/¯] @[¯\_(?)_/¯] NVARCHAR(20) AS SELECT [¯\_(?)_/¯] FROM [¯\_(?)_/¯].[vw_¯\_(?)_/¯] WHERE [¯\_(?)_/¯] …
Run Code Online (Sandbox Code Playgroud)

sql-server stored-procedures t-sql parameter unicode

53
推荐指数
2
解决办法
5505
查看次数

被要求不使用事务并使用一种解决方法来模拟一个

我已经开发 T-SQL 好几年了,并且一直在深入挖掘,继续尽我所能学习语言的各个方面。我最近开始在一家新公司工作,并收到了我认为关于交易的奇怪建议。永远不要使用它们。相反,使用模拟事务的解决方法。这是来自我们的 DBA,他在一个数据库中工作,有很多事务,随后有很多阻塞。我主要工作的数据库没有遇到这个问题,我看到过去曾使用过事务。

我知道阻塞是预期的交易,因为这样做是他们的本性,如果你可以不使用它而逃脱,一定要这样做。但是我有很多情况下每个语句都必须成功执行。如果一个失败,他们都必须失败。

我总是尽可能缩小我的事务范围,总是与 SET XACT_ABORT ON 结合使用,并且总是在 TRY/CATCH 内。

例子:

CREATE SCHEMA someschema;
GO


CREATE TABLE someschema.tableA
(id   INT NOT NULL IDENTITY(1, 1) PRIMARY KEY, 
 ColA VARCHAR(10) NOT NULL
);
GO

CREATE TABLE someschema.tableB
(id   INT NOT NULL IDENTITY(1, 1) PRIMARY KEY, 
 ColB VARCHAR(10) NOT NULL
); 
GO


CREATE PROCEDURE someschema.ProcedureName @ColA VARCHAR(10), 
                                          @ColB VARCHAR(10)
AS
SET NOCOUNT, XACT_ABORT ON;
BEGIN
BEGIN TRY
    BEGIN TRANSACTION;

    INSERT INTO someschema.tableA(ColA)
    VALUES(@ColA);

    INSERT INTO someschema.tableB(ColB)
    VALUES(@ColB);

--Implement error
    SELECT 1/0 …
Run Code Online (Sandbox Code Playgroud)

sql-server t-sql transaction

45
推荐指数
5
解决办法
5888
查看次数

将选择结果写入 csv 文件

我们需要将 SELECT 查询结果写入一个 csv 文件。如何在 SQL Server 2008 r2 中使用 T-SQL 来完成?我知道它可以在 SSIS 中完成,但由于某些原因,我们没有这个选项。

我尝试使用下面文章中建议的 proc,但是当我运行该 proc 时,SQL 抱怨无法运行在此 proc 中调用的 sys.sp_OACreate 和 sys.sp_OADestroy。

您知道我们如何打开这些组件或知道使用 T-SQL 写入文件的更好方法吗?

提前致谢。

sql-server-2008 t-sql

44
推荐指数
5
解决办法
30万
查看次数

表值参数作为存储过程的输出参数

是否可以将表值参数用作存储过程的输出参数?

这是,我想在代码中做什么

/*First I create MY type */
CREATE TYPE typ_test AS TABLE 
(
     id int not null
    ,name varchar(50) not null
    ,value varchar(50) not null
    PRIMARY KEY (id)
)
GO


--Now I want to create stored procedu whic is going to send output type I created, 
--But it looks like it is inpossible, at least in SQL2008
create  PROCEDURE [dbo].sp_test
         @od datetime 
        ,@do datetime 
        ,@poruka varchar(Max) output
        ,@iznos money output 
        ,@racun_stavke  dbo.typ_test   READONLY --Can I Change READONLY with OUTPUT …
Run Code Online (Sandbox Code Playgroud)

sql-server-2008 stored-procedures datatypes t-sql parameter

39
推荐指数
1
解决办法
7万
查看次数