这个查询有效
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 中地址的门牌号的可能变化
我想做的是为每个建筑物地址创建一个笛卡尔积,其中包含其街道名称的所有可能变体和门牌号的所有可能变体。
例如
有时候我们需要对某些表进行批量更新,而帮助数据库在正常使用中顺利运行的索引就成为了一个障碍。因此,我们禁用该表上的所有索引,执行更新,然后重新启用它们。要禁用表“x”上的所有索引,我们运行 t-sql 语句:
ALTER INDEX ALL ON x DISABLE
Run Code Online (Sandbox Code Playgroud)
这会导致一大堆警告,例如:
警告:由于禁用表上的聚集索引,表“x”上的索引“y”被禁用。
这很公平,但我们知道我们在做什么,所以这些警告只是噪音。
是否可以添加类似于 DBCC 命令上的 NO_INFOMSGS 参数的内容来抑制这些不需要的警告?
我最近读完 《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
我正在尝试使用触发器捕获登录时间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) 报告当前计算“总计”列,如下所示:
,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”时,如何获得空白单元格,并避免进行两次计算?
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) 我以为我已经确定了这个语法,但是当我尝试执行时,我收到了 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 以查询我从列表中创建的服务器,以跟踪事务日志备份历史记录。
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) 如何在 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 语句。
当我在不指定 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)