标签: t-sql

T-SQL 不支持相关的 CROSS JOIN 吗?

这个查询有效

SELECT      QMC.HAUSKEY, t1.STRNAME, t2.HAUS_NR
FROM        SWOPS.MIGR.QMCAddresses QMC
CROSS JOIN  (SELECT STRNAME FROM SWOPS.MIGR.EB_DICT_STREET_QMC  WHERE FK=8055909) t1
CROSS JOIN  (SELECT HAUS_NR FROM SWOPS.MIGR.EB_DICT_HAUSNR_QMC  WHERE FK=8055909) t2
WHERE       1=1
        AND QMC.HAUSKEY=8055909
ORDER BY    HAUSKEY, t1.STRNAME, t2.HAUS_NR
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

但是,当我用列引用 QMC.HAUSKEY 替换 CROSS JOIN 子查询中的常量 8055909 时,查询报告错误

Msg 4104, Level 16, State 1, Line 56 The multi-part identifier "QMC.HAUSKEY" could not be bound.

这是为什么?

背景:

QMCAddresses 包含建筑物及其地址

EB_DICT_STREET_QMC 包含 QMCAddresses 中地址的街道名称的可能变体

EB_DICT_STREET_HAUSNR 包含 QMCAddresses 中地址的门牌号的可能变化

我想做的是为每个建筑物地址创建一个笛卡尔积,其中包含其街道名称的所有可能变体和门牌号的所有可能变体。

例如

在此输入图像描述

sql-server t-sql subquery cross-join

0
推荐指数
1
解决办法
227
查看次数

禁用 SQL Server 中表上的所有索引而不显示警告消息

有时候我们需要对某些表进行批量更新,而帮助数据库在正常使用中顺利运行的索引就成为了一个障碍。因此,我们禁用该表上的所有索引,执行更新,然后重新启用它们。要禁用表“x”上的所有索引,我们运行 t-sql 语句:

ALTER INDEX ALL ON x DISABLE
Run Code Online (Sandbox Code Playgroud)

这会导致一大堆警告,例如:

警告:由于禁用表上的聚集索引,表“x”上的索引“y”被禁用。

这很公平,但我们知道我们在做什么,所以这些警告只是噪音。

是否可以添加类似于 DBCC 命令上的 NO_INFOMSGS 参数的内容来抑制这些不需要的警告?

sql-server t-sql

0
推荐指数
1
解决办法
502
查看次数

除了显式刷新缓存或要求重新编译之外,什么会重新编译 SQL Server 2019 中的完整存储过程?

我最近读完 《SQL Server 2008 中的计划缓存》 ,我感到很困惑。看起来,除了完全刷新计划缓存或明确要求重新编译存储过程之外,从 SQL Server 2008 开始,存储过程的重新编译都是在语句级别而不是存储过程级别完成的。

那么,除了显式刷新缓存或要求重新编译(例如WITH RECOMPILE)之外,什么可以在 SQL Server 2019 中重新编译完整的存储过程,而不仅仅是重新编译单个语句呢?

举一个我感到困惑的例子,请考虑以下过程。

CREATE PROCEDURE FOO AS
BEGIN
   SELECT * INTO #temp1 FROM table1
   INSERT BAR1 SELECT * FROM #temp1
   INSERT BAR2 SELECT * FROM #temp1
END
Run Code Online (Sandbox Code Playgroud)

我可以想到很多可能导致SELECT * INTO #temp1 FROM table1重新编译的事情,但是如果没有下一行也重新编译,那么重新编译会很奇怪。这让我觉得 SQL Server 中一定有一些东西会导致整个存储过程重新编译。

stored-procedures t-sql execution-plan recompile sql-server-2019

0
推荐指数
1
解决办法
182
查看次数

EVENTDATA() 函数在 SQL Server 中仅给出空值

我正在尝试使用触发器捕获登录时间EVENTDATA()。但它只为所有类型的事件提供 Null 值。有人可以帮我解决这个问题吗?这是我的触发器

CREATE TRIGGER trgBlockIP
    ON ALL SERVER
    FOR LOGON
    AS
    BEGIN
       DECLARE @clientip NVARCHAR(15);
       SET @clientip = (
                          SELECT
                             EVENTDATA().value(
                                                 '(/EVENT_INSTANCE/Clienthost)[1]',
                                                 'NVARCHAR(15)'
                                              )
                       );
       IF EXISTS (
                    SELECT ip
                    FROM   master.dbo.BLockedIPAddresses
                    WHERE  ip = @clientip
                 )
       BEGIN
          PRINT 'Your IP Address is blocked';
          ROLLBACK;
       END;
       ELSE
       BEGIN
          DECLARE @Range VARCHAR(15);
          SELECT
             @Range = SUBSTRING(
                                  @clientip,
                                  1,
                                  LEN(@clientip)
                                  - CHARINDEX('.', REVERSE(@clientip))
                               ) + '.*';
          IF EXISTS (
                       SELECT ip
                       FROM   master.dbo.BLockedIPAddresses
                       WHERE  ip = @Range
                    )
          BEGIN …
Run Code Online (Sandbox Code Playgroud)

trigger sql-server-2008 sql-server t-sql functions

0
推荐指数
1
解决办法
80
查看次数

总计列 - 如果为零或 NULL 则为空白

报告当前计算“总计”列,如下所示:

,CASE WHEN ISNULL(CLM_BREAKFAST_TYPEA.MealsA, 0) +
           ISNULL(CLM_BREAKFAST_TYPEB.MealsB, 0) = 0                 
      THEN ''
      ELSE CONVERT(VARCHAR(15), 
           ISNULL(CLM_BREAKFAST_TYPEA.MealsA, 0) +
           ISNULL(CLM_BREAKFAST_TYPEB.MealsB, 0)) 
      END AS 'MealsTotal'
Run Code Online (Sandbox Code Playgroud)

当总数等于零而不是 NULL 或“0”时,如何获得空白单元格,并避免进行两次计算?

null sql-server t-sql

-1
推荐指数
1
解决办法
1465
查看次数

验证此 TSQL 以查找碎片化超过 50% 的索引

select 
OBJECT_SCHEMA_NAME(IPS.object_id) 'schema',
  OBJECT_NAME(IPS.object_id) as table_name,index_type_desc,
  round(avg_fragmentation_in_percent,2) 'avg_fragmentation_in_percent',
  si.name
   from  sys.dm_db_index_physical_stats(db_id(DB_NAME()),null, 
   NULL, NULL , 'DETAILED') AS IPS inner join  sys.indexes si on 
   si.object_id=IPS.object_id
   where
   index_type_desc <> 'HEAP' and avg_fragmentation_in_percent >=50
   order by avg_fragmentation_in_percent desc
Run Code Online (Sandbox Code Playgroud)

index sql-server-2008 sql-server t-sql fragmentation

-1
推荐指数
1
解决办法
361
查看次数

在更新语句中使用 SUM()

我以为我已经确定了这个语法,但是当我尝试执行时,我收到了 Incorrect syntax near ) 的错误。为什么我的语法不正确?

    ;with CTE As
    (
         Select max(entryID) As "MaxEntryID"
         ,userID FROM loghist group by userID
    )
    Select es.userID As userID, cm.companyName, SUM(COALESCE(eq.TotalValue,0)) As TotalValue
    FROM CTE vn
    Inner Join loghist es
    ON vn.userID=es.userID
    AND Coalesce(vn."MaxEntryID",0)=COALESCE(es.entryID,0)
    INNER JOIN company cm
    ON es.customerid = cm.customerid    
    Inner Join loghistpart ep
    ON ep.loghist = es.loghistid
    Inner Join lhq eq
    On eq.loghistpartid = ep.loghistpartid
    GROUP BY es.userID, cm.companyName
)
UPDATE fvi
Set TotalValue = loghistdTotalValue
FROM FullVarianceInfo fvi
INNER JOIN …
Run Code Online (Sandbox Code Playgroud)

sql-server cte t-sql sql-server-2008-r2 update

-1
推荐指数
1
解决办法
1080
查看次数

如何重写此存储过程以不使用游标?

我想更改我的存储过程,使其不再使用游标来运行。我怎样才能更好地编写这个存储过程?

我正在使用游标编译动态 SQL 以查询我从列表中创建的服务器,以跟踪事务日志备份历史记录。

ALTER PROC [dbo].[spLogBackup]

AS

TRUNCATE TABLE dbo.tLogBackup

DECLARE servers_cursor CURSOR
FOR
select  distinct LinkedserverName
from dbo.Environment
join master..sysservers on srvname COLLATE DATABASE_DEFAULT  = LinkedserverName COLLATE DATABASE_DEFAULT
where LinkedServerName not in ('TestDB')

and ServerUse in ('PROD', 'DR')
and IncludeInstats = 1
order by LinkedServerName

OPEN servers_cursor
DECLARE @Servername varchar(250)

DECLARE @sql varchar(8000)

FETCH NEXT FROM servers_cursor INTO @ServerName
WHILE (@@FETCH_STATUS = 0)
BEGIN
    --Looping throught the servers.
    set @sql = 'insert into dbo.tLogBackup (servername, rundate, runtime, jobname, …
Run Code Online (Sandbox Code Playgroud)

sql-server stored-procedures t-sql

-1
推荐指数
1
解决办法
173
查看次数

使用 IF...ELSE 的多个查询

如何在 IF“子句”中做多项事情?我真的可以只做一个动作吗?我在谷歌上搜索了“sql server scope”,但它返回了一堆关于“scope_identity”的无关内容,而没有关于语法......

例子:

DECLARE @db_level int = 2

DECLARE @db_major int = 1
DECLARE @db_minor int = 0
DECLARE @db_point int = 0

DECLARE @db_current_level int = (SELECT MAX(db_level) FROM db_schema_log_tb)

IF (@db_level > @db_current_level)
    PRINT 'Script failed because database level is higher than script level';
    GOTO ExitScript;
ELSE
    SELECT * FROM custom_tb;

ExitScript:
Run Code Online (Sandbox Code Playgroud)

显然,这个脚本中的 ELSE 是不正确的语法,除非我删除了 PRINT 语句。

sql-server t-sql

-1
推荐指数
1
解决办法
1040
查看次数

仅使用 ldf 文件创建数据库创建了 2 个 .ldf 文件

当我在不指定 ldf 文件的情况下运行此查询时,它会自动创建 ldf 文件。

Declare @DBname nvarchar(50) = 'Test'
Declare @path nvarchar(50) = 'D:\DB'
Declare @query nvarchar(max) 

set @query = '

CREATE DATABASE ' + @DBname + '
ON
( NAME = ' +@DBname+',  
    FILENAME = '''+@path+'\'+@DBname+'.mdf'+''',
    SIZE = 1024,
    MAXSIZE = unlimited,
    FILEGROWTH = 500 )  
'
exec (@query)
Run Code Online (Sandbox Code Playgroud)

但是当我运行这个查询时:

Declare @DBname nvarchar(50) = 'Test'
Declare @path nvarchar(50) = 'D:\DB'
Declare @query nvarchar(max) 

set @query = '

CREATE DATABASE ' + @DBname + '
ON 
( NAME = …
Run Code Online (Sandbox Code Playgroud)

sql-server t-sql sql-server-2012

-1
推荐指数
1
解决办法
149
查看次数