SQL Server 2019 引入了一个新的(未记录的)系统存储过程:
sys.xp_delete_files
这个新的扩展存储过程到底是做什么的?它与xp_delete_file
多年来一直存在的有什么不同?它取代xp_delete_file
吗?
SQL Server 2019 引入了一个新的(未记录的)系统存储过程:
sys.xp_delete_files
这个新的扩展存储过程到底是做什么的?它与xp_delete_file
多年来一直存在的有什么不同?它取代xp_delete_file
吗?
我有几个版本的 SQL Server,用于测试,安装在我的笔记本电脑上(2012、2014、2016 和 2017)。前几天我注意到有一个文件夹包含跨更新(SP、CU)的文件的早期版本。在所有版本中,实际上占用了相当多的空间:
(在C:\Program Files (x86)\Microsoft SQL Server\中)
110\Setup Bootstrap\Log - 91.8 MB (818 files)
110\Setup Bootstrap\Update Cache - 608 MB (2,382 files)
(下面的所有文件夹都位于:C:\Program Files\Microsoft SQL Server\)
110\Setup Bootstrap\Log - 1.18 GB (3,715 files)
110\Setup Bootstrap\Update Cache - 9.58 GB (14,766 files)
120\Setup Bootstrap\Log - 569 MB (2,963 files)
120\Setup Bootstrap\Update Cache - 5.74 GB (12,797 files)
130\Setup Bootstrap\Log - 448 MB (2,808 files)
130\Setup Bootstrap\Update Cache - 3.84 GB (8,579 files)
140\Setup Bootstrap\Log - 84.3 MB (687 files)
140\Setup Bootstrap\Update Cache - 937 MB (1,571 Files)
这些文件夹的总数为(MB 已标准化为 GB):
Folder GB Files
---------- ----- ------
Log 2.35 10,991
Update Cache 20.66 40,095
TOTAL 23.01 51,086
最初我认为删除Log和Update Cache文件夹应该是安全的,但后来我认为最好先检查一下其他人是否问过这个问题,如果是,答案是什么。我找到了这篇知识库文章:
其中指出:
如果您删除此文件夹或删除其内容会怎样?
如果从该文件夹中删除了 Update Cache 文件夹或某些修补程序,则不能再卸载 SQL Server 实例的更新,然后再恢复到较早的更新版本。在这种情况下,添加/删除程序条目指向不存在的二进制文件,因此卸载过程不起作用。因此,Microsoft 强烈建议您保持文件夹及其内容的完整性。
好的。我没有降级或卸载 SP 或 CU 的计划,所以我应该没问题,对吧?好吧,还有其他参考资料,例如这个:
其中有人引用了以下知识库文章:
如何还原丢失的 Windows Installer 缓存文件并解决 SQL Server 更新期间出现的问题
其中指出(强调):
安装 SQL Server 时,Windows Installer 将关键文件存储在 Windows Installer 缓存中(默认为 C:\Windows\Installer)。卸载和更新应用程序需要这些文件。
现在,这篇特定的文章似乎特定于C:\Windows\Installer文件夹,我不是在谈论从该文件夹中删除。尽管如此,由于提到了无法应用更新的可能性,我首先想要更多信息。
以前有没有人删除过这些文件夹,或者至少只是删除了它们的内容?如果是这样,是否有任何负面影响?这些文件夹只会增加。我刚刚为所有四个版本应用了“Spectre / Meltdown”补丁,总数增加了 3.65 GB 和 6,900 个文件(最终结果如上图所示)。
需要明确的是,我不是在寻找是否应该删除这些文件夹中的一个或两个;我正在寻找我是否可以删除一个或两个(除了卸载/降级的能力之外,我已经接受了这一点)。
我有时有一个 SQL 脚本,其中包含一个或多个超长(有时甚至是愚蠢的长)字符串。通常这些是VARBINARY
代表文件/程序集的文字/常量,但有时它们是文本。
真正长字符串的主要问题是一些文本编辑器不能很好地处理它们。例如,我有一个VARBINARY
在语句中使用的文字CREATE ASSEMBLY [AssemblyName] FROM 0x....
,而程序集本身的大小刚刚超过 1 MB,这相当于文本文件中超过 200 万个字符,因为每个字节需要两个字符以十六进制表示法表示(例如0x1F
= a1
和 an F
)。SQL Server Management Studio (SSMS) 不能很好地处理这个问题,并在我尝试滚动该行时挂起几秒钟。事实上,某些版本(不确定是否仍然会发生这种情况)甚至会在打开至少有一行超过一定长度的脚本时显示关于长行的警告。
第二个问题是,当在没有启用自动换行的编辑器中使用或在线发布时,它会使格式复杂化。这里的问题是水平滚动条的滑块非常窄,即使移动它一点点通常也会将非超长文本滚动到视野之外。
现在,T-SQL 不会用换行符甚至分号来终止命令(尽管从 SQL Server 2005 开始,分号是首选/推荐的)。因此,由于 SQL Server 知道如何解析每条语句以使其知道何时结束,因此似乎将长行拆分为多行,仅由newline/ carriage-return+分隔line-feed,这似乎并不合理。但这在任何一种情况下都不起作用。
PRINT 'Line1
Line2';
返回(在“消息”选项卡中):
Line1
Line2
这很有意义,因为换行符在文字/常量内。但是这样做VARBINARY
也行不通。
PRINT 0x1234
5678;
给我一个错误。
我有一个 pre-SQL Server 2017 数据库,我将它还原到/升级到 SQL Server 2017。在这个数据库中,我有一个 SQLCLR 程序集。该程序集被标记为,SAFE
因为它不执行任何需要更高级别权限的操作,并且数据库已TRUSTWORTHY
禁用 / OFF
。SQLCLR 函数和存储过程在迁移到 SQL Server 2017 之前按预期工作,但现在当我尝试执行其中任何一个时,我收到以下错误:
消息 10314,级别 16,状态 11,服务器 XXXXXXXXXXX,行 YYYYYY
尝试加载程序集 ID ZZZZZ 时,Microsoft .NET Framework 中发生错误。服务器可能资源不足,或者程序集可能不受信任。再次运行查询,或查看文档以了解如何解决程序集信任问题。有关此错误的更多信息:
System.IO.FileLoadException:无法加载文件或程序集“{assembly_name},版本=0.0.0.0,Culture=neutral,PublicKeyToken=null”或其依赖项之一。发生与安全有关的错误。(来自 HRESULT 的异常:0x8013150A)
我已经确认在服务器/实例上启用了 CLR 集成/SQLCLR。
我在 Linux (Ubuntu 16.04) 上使用 SQL Server 2017,Release Candidate 2 (RC2)。
当服务器启动时,SQL Server 通常也会启动。但由于某种原因,SQL Server 将不再启动。至少我无法使用sqlcmd连接到它。我现在每次都收到 ODBC 超时(“Sqlcmd:错误:Microsoft ODBC Driver 13 for SQL Server ”)错误:
Login timeout expired.
TCP Provider: Error code 0x2749.
A network-related or instance-specific error has occurred while establishing a
connection to SQL Server. Server is not found or not accessible. Check if instance
name is correct and if SQL Server is configured to allow remote connections.
For more information see SQL Server Books Online..
但是,当我运行时:
ps aux | grep mssql
我收到两个返回的条目,表明mssql
用户正在运行该sqlservr
进程。
此外,/var/opt/mssql/log/中的错误日志文件在我启动 VM(或重新启动服务)时没有时间戳匹配,该文件中也没有任何新条目。
并且,在/var/log/messages中,所有显示的是:
这是一个评估版本。评估期还剩 [141] 天。
如果我运行systemctl status mssql-server
,那么我会得到以下信息:
● mssql-server.service - Microsoft SQL Server 数据库引擎
已加载:已加载(/lib/systemd/system/mssql-server.service;已启用;供应商预设:已启用)
活动:自 2017 年星期一以来失败(结果:退出代码)- 09-04 20:01:56 英国夏令时;36 秒前
文档:https
://learn.microsoft.com/en-us/sql/linux 进程:8009 ExecStart=/opt/mssql/bin/sqlservr(code=exited,status=255)
主 PID:8009(code=退出,状态=255)Started Microsoft SQL Server Database Engine. This is an evaluation version. There are [141] days left in the evaluation period. Stopping Microsoft SQL Server Database Engine... mssql-server.service: Main process exited, code=exited, status=255/n/a Stopped Microsoft SQL Server Database Engine. mssql-server.service: Unit entered failed state. mssql-server.service: Failed with result 'exit-code'.
我才发现,通过纯粹的光彩意外地,那个 SQL Server 允许您创建没有任何名称的变量、参数、表变量、临时表(本地和全局)和临时存储过程(本地和全局)!好吧,至少不是我认为的名字。意思是,您可以指定DECLARE @ INT = 5;
它是有效的 T-SQL:它执行时没有错误,甚至在 SSMS 中都没有用红色波浪下划线标记(本问题末尾显示了带有完整示例列表的代码)。
鉴于数据库标识符的 MSDN 页面指出(强调我的):
有两类标识符:
常规标识符
...定界
标识符
... 常规标识符和定界标识符都必须包含1 到128 个字符。对于本地临时表,标识符最多可以包含 116 个字符。
这当然看起来不像预期的行为,我最初认为这是一个缺陷(不会导致任何错误,但似乎不是“正确”的行为)并提交了一个连接错误:Parameter, Variable, and Temporary表和过程名称/标识符可以为空。
但是,同一个 MSDN 页面还指出:
常规标识符的规则
变量、函数和存储过程的名称必须符合以下 Transact-SQL 标识符规则。
第一个字符必须是以下之一:
- Unicode 标准 3.2 定义的字母。字母的 Unicode 定义包括从 a 到 z、从 A 到 Z 的拉丁字符,以及来自其他语言的字母字符。
下划线 (_)、at 符号 (@) 或井号 (#)。
标识符开头的某些符号在 SQL Server 中具有特殊含义。以 at 符号开头的常规标识符始终表示局部变量或参数,不能用作任何其他类型对象的名称。以数字符号开头的标识符表示临时表或过程。以双数字符号 (##) 开头的标识符表示全局临时对象。尽管数字符号或双数字符号字符可用于开始其他类型的对象的名称,但我们不推荐这种做法。
因此,可以解释为名称的 1 个字符的最低要求(从最上面引用的显示“1 到 128 个字符”的部分)可以通过简单地满足以下任一@
或以下条件#
:
@
或#
是第一个字符时,需要2 到128 个字符。那么,如果这种行为既不是错误也不是缺陷,那么利用这种能力有什么好处吗?是否有合法的用例可以通过执行此操作而受益(即对项目的某些功能性好处,而不仅仅是减少源代码的字符数)?
我想不出一个,除了不专业和在你搬到新雇主时为每个人留下可怕的难以管理的代码之外。
但我也可以看到一个相关的功能问题,因为在许多解析 T-SQL 对象的项目中有许多代码块。如果有人使用 RegEx 模式查找@
后跟诸如 之类的(\w+)
内容,那么它将跳过这些条目。
-- Local variables:
DECLARE @ INT = 99;
DECLARE @@ VARCHAR(10);
SELECT CONVERT(VARCHAR(20), @), STR(@);
SET @@ = STR(@);
SELECT @@;
GO
-- Table Variable:
DECLARE @ TABLE (Col1 INT);
INSERT INTO @ (Col1) VALUES (86);
SELECT * FROM @;
GO
-- Local Temporary Table:
CREATE TABLE # (Col2 DATETIME);
INSERT INTO # (Col2) VALUES (GETDATE());
SELECT * FROM #;
SELECT OBJECT_ID(N'tempdb..#');
GO
-- Global Temporary Stored Procedure
CREATE PROCEDURE ## ( @ INT = 999 )
AS
SELECT @ AS [Huh?];
GO
EXEC ##;
EXEC ## 204;
DECLARE @ INT = 12345;
EXEC ## @ = @;
-- The above also work in another session on the same instance, in a different Database
SELECT * FROM tempdb.sys.parameters tsp WHERE tsp.[object_id] = OBJECT_ID(N'tempdb..##');
-- returns 1 row showing a name of just "@"
PS 我在这里、谷歌和 Microsoft Connect 上搜索过,但找不到任何对“缺失”或“空”变量名或“标识符”的引用。但是,@MartinSmith 确实指出了以下 StackOverflow 答案中使用的这种“能力”以减少代码的字符数:Building an ASCII chart of the most commonly used words in a given text。
我创建了一些证书(通过CREATE CERTIFICATE)和非对称密钥(通过CREATE ASYMMETRIC KEY),并使用它们对各种存储过程、用户定义函数(UDF)、触发器和程序集(通过ADD SIGNATURE)进行签名和副签名. 但现在我需要找出哪些证书和/或非对称密钥已用于签署哪些特定模块。
我需要创建一些涉及层次结构的测试数据。我可以让它变得简单并做几个CROSS JOIN
s,但这会给我一个完全统一/没有任何变化的结构。这不仅看起来乏味,而且测试数据缺乏变化有时会掩盖原本会发现的问题。所以,我想生成一个遵循这些规则的非统一层次结构:
WHILE
循环很容易地完成,但首选是找到基于集合的方法。一般来说,生成测试数据并没有生产代码对效率的要求,但采用基于集合的方法可能更具教育意义,并有助于在未来找到基于集合的方法来解决问题。因此WHILE
不排除循环,但只能在不可能使用基于集合的方法时使用。[ CROSS | OUTER ] APPLY
,这在上面说明是可以的。我不确定这些附加信息是否重要,但以防万一它有助于了解一些上下文,测试数据与我对这个问题的回答有关:
虽然此时不相关,但生成此层次结构的最终目标是创建一个目录结构来测试递归文件系统方法。级别 1 和 2 将是目录,而级别 3 将最终成为文件名。我已经搜索了(在这里和通过谷歌)并且只找到了一个生成随机层次结构的参考:
这个问题(在 StackOverflow 上)实际上与期望的结果非常接近,因为它也试图创建一个用于测试的目录结构。但这个问题(和答案)集中在 Linux/Unix shell 脚本,而不是我们生活的基于集合的世界。
现在,我知道如何生成随机数据,并且已经在这样做以创建文件的内容,以便它们也可以显示变化。这里棘手的部分是每个集合中的元素数量是随机的,而不是特定的字段。并且,每个节点内的元素数量需要与同一级别上的其他节点随机。
示例层次结构
Level 1
Level 3
|---- A
| |-- 1
| | |--- I
| |
| |-- 2
| |--- III
| |--- VI
| |--- VII
| |--- IX
|
|---- B
| |-- 87
| |--- AAA
| |--- DDD
|
|---- C
|-- ASDF
| |--- 11
| |--- 22
| |--- 33
|
|-- QWERTY
| |--- beft
|
|-- ROYGBP
|--- Poi
|--- Moi
|--- Soy
|--- Joy
|--- Roy
描述上述层次结构的示例结果集
Level 1 Level 2 Level 3
A 1 I
A 2 III
A 2 VI
A 2 VII
A 2 IX
B 87 AAA
B 87 DDD
C ASDF 11
C ASDF 22
C ASDF 33
C QWERTY beft
C ROYGBP Poi
C ROYGBP Moi
C ROYGBP Soy
C ROYGBP Joy
C ROYGBP Roy