标签: t-sql

如何使用 FOR XML 从子元素中删除 xmlns

我有一个用于生成 SOAP 文档的 TSQL 查询。我正在使用两个命名空间。即: - http://schemas.xmlsoap.org/soap/envelope/用于“打包”soap 文档 - 描述正文中包含的数据的自定义文档

目前,包括正文中的元素在内的每个元素都包含我不需要且想要的soapnamespace 引用,我只希望它位于根元素中。

所以我的 XML 现在看起来像

<soapenv:Envelope xmlns="soapenv" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:pas="foobar">
    <soapenv:Header xmlns="soapenv" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:pas="foobar" />
            <soapenv:Body xmlns="soapenv" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:pas="foobar">
                    <pas:SomeObject xmlns="soapenv" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:pas="foobar">
Run Code Online (Sandbox Code Playgroud)

我希望它看起来像

<soapenv:Envelope xmlns="soapenv" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:pas="foobar">
    <soapenv:Header/>
            <soapenv:Body>
                    <pas:SomeObject>
Run Code Online (Sandbox Code Playgroud)

在我当前使用的查询中

;WITH XMLNAMESPACES ( 'http://foobar' as pas,
      'http://schemas.xmlsoap.org/soap/envelope/' as soapenv
      )
SELECT (SELECT '' FOR XML PATH('soapenv:Header'),type ),
etc...
FOR XML PATH('soapenv:Envelope'), ELEMENTS
Run Code Online (Sandbox Code Playgroud)

xml t-sql

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

SSMS 中表的哪些更改会导致 DROP/CREATE,并且可以使用 TSQL 始终避免这种情况吗?

我知道在某些情况下,通过 SSMS 的 GUI 对表进行某些更改(例如,更改列的类型)将导致表被删除并重新创建。

我的问题是,对于导致这种行为的具体变化是否存在完整的定义?通过运行而不是使用 SSMS GUI 是否可以始终避免这种行为ALTER TABLE(如果不能,哪些可以避免,哪些不能)?

sql-server ssms t-sql alter-table

5
推荐指数
1
解决办法
206
查看次数

有没有办法使用 sysconv() 内置函数?

如果您使用以下方法获取某些视图的定义sys.sp_helptext

exec sys.sp_helptext 'sys.columns'

CREATE VIEW sys.columns
AS
  SELECT c.id                                                             AS object_id,
         c.NAME,
         c.colid                                                          AS column_id,
         c.xtype                                                          AS system_type_id,
         c.utype                                                          AS user_type_id,
         c.length                                                         AS max_length,
         c.prec                                                           AS PRECISION,
         c.scale,
         CONVERT(SYSNAME, CollationPropertyFromId(c.collationid, 'name')) AS collation_name,
         sysconv(bit, 1 - ( c.status & 1 ))                               AS is_nullable,-- CPM_NOTNULL  
         sysconv(bit, c.status & 2)                                       AS is_ansi_padded,-- CPM_NOTRIM  
         sysconv(bit, c.status & 8)                                       AS is_rowguidcol,-- CPM_ROWGUIDCOL  
         sysconv(bit, c.status & 4)                                       AS is_identity,-- CPM_IDENTCOL  
         sysconv(bit, c.status & 16)                                      AS is_computed,-- CPM_COMPUTED  
         sysconv(bit, c.status & 32)                                      AS …
Run Code Online (Sandbox Code Playgroud)

sql-server t-sql

5
推荐指数
1
解决办法
1197
查看次数

在使用 TRY CATCH 的 SQL Server 中提交事务的最佳实践

在 SQL Server 代码块中,放置提交事务的最佳位置是什么?在 try catch 块内部还是外部?

例如,选项 A 或选项 B 是正确的方法还是主观选择?

选项A

CREATE PROCEDURE DummyProc 
BEGIN TRY
      BEGIN TRANSACTION
      INSERT sometable(a, b) VALUES (@a, @b)
      INSERT sometable(a, b) VALUES (@b, @a)
      COMMIT TRANSACTION
   END TRY
   BEGIN CATCH
      IF @@trancount > 0 ROLLBACK TRANSACTION
      DECLARE @msg nvarchar(2048) = error_message()  
      RAISERROR (@msg, 16, 1)
      RETURN 55555
   END CATCH   
Run Code Online (Sandbox Code Playgroud)

选项B

CREATE PROCEDURE DummyProc 
BEGIN TRY
      BEGIN TRANSACTION
      INSERT sometable(a, b) VALUES (@a, @b)
      INSERT sometable(a, b) VALUES (@b, @a)

   END TRY
   BEGIN …
Run Code Online (Sandbox Code Playgroud)

sql-server t-sql transaction exception code

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

有没有办法从备份文件中检索逻辑文件名?

我想编写一个自动化脚本来从备份文件恢复 SQL Server 数据库。然而,在 SQL 中执行此操作并不是一个简单的过程,因为主查询需要额外的输入,而这些输入实际上可以使用另一个查询来获取。我可以在一个查询中完成此操作吗?

SO 已经有一个问题;但解决方案不是很灵活RESTORE FILELISTONLY的定义变化非常频繁。即便如此,该解决方案似乎也非常冗长。

是否有更简单的方法将查询结果存储到变量中并使用它们?对于任何编程语言来说,这都是小菜一碟。

获取逻辑名称:

RESTORE FILELISTONLY
FROM DISK = 'D:SourceBackUpFile.bak'
GO
Run Code Online (Sandbox Code Playgroud)

恢复数据库:

RESTORE DATABASE DBName
FROM DISK = 'D:SourceBackUpFile.bak'
WITH RECOVERY
MOVE 'SourceMDFLogicalName' TO 'D:TargetMDFFile.mdf',
MOVE 'SourceLDFLogicalName' TO 'D:TargetLDFFile.ldf'
Run Code Online (Sandbox Code Playgroud)

sql-server backup t-sql

5
推荐指数
1
解决办法
3491
查看次数

正确转义 JSON 字符串中的字符

在下面的示例中,如何转义 @data 变量中的双引号字符?

declare @data nvarchar(max) = N'"TEST"';
declare @jsonFragment nvarchar(max);
declare @id int = 999;

set @jsonFragment = ',"' + cast(@id as nvarchar(16)) + '":"' + @data + '"';

select @jsonFragment;
Run Code Online (Sandbox Code Playgroud)

结果是:

 ,"999":""TEST""
Run Code Online (Sandbox Code Playgroud)

我需要它是:

 ,"999":"\"TEST\""
Run Code Online (Sandbox Code Playgroud)

据我了解,选择for json path要求我定义一个静态键名称 - 但可以看出,我有一个场景,其中键名称是动态定义的。

在我的实际用例中,此字符串构造发生在一个stuff语句内,该语句本身是利用 CTE 的较大列定义的一部分select- 这意味着很难创建要使用sp_executeSQL.

t-sql json sql-server-2016

5
推荐指数
1
解决办法
8174
查看次数

获取消息 15151,无法更改用户“xxxx”,因为它不存在或您没有权限

我有以下脚本,但执行时不断出现错误。

USE [master]
GO

If Not EXISTS (Select loginname from [master].[dbo].[syslogins]
    Where name = 'xxxx' and dbname = 'xxxx-xxxx')
BEGIN
    CREATE LOGIN [xxxx] WITH PASSWORD=N'xxxxx', DEFAULT_DATABASE=[xxxx-xxxx], DEFAULT_LANGUAGE=[us_english], CHECK_EXPIRATION=OFF, CHECK_POLICY=OFF
    ALTER LOGIN [xxxx] ENABLE
END
GO

USE [xxxx-xxxx]
ALTER USER [xxxx] WITH DEFAULT_SCHEMA=[db_datareader]
ALTER ROLE [db_datareader] ADD MEMBER [xxxx]
ALTER ROLE [db_datawriter] ADD MEMBER [xxxx]
ALTER ROLE [db_owner] ADD MEMBER [xxxx]
GO
Run Code Online (Sandbox Code Playgroud)

我尝试了该脚本的几种排列,但没有成功。它确实创建了登录名,但不允许我更改“用户”或“角色”属性。当我可以让它正常工作时,它不会对用户配置文件进行更改。

sql-server t-sql

5
推荐指数
1
解决办法
5740
查看次数

无法打开数据库。正在恢复中

我已经执行了这两个命令:

USE master
GO

RESTORE DATABASE test
FROM Kingston
WITH NORECOVERY
GO
Run Code Online (Sandbox Code Playgroud)
USE master
GO
RESTORE LOG test
FROM Kingston
WITH STOPAT = '2020-05-13 14:05:25', RECOVERY;
GO
Run Code Online (Sandbox Code Playgroud)

但现在我在访问数据库时遇到此错误USE test GO

无法打开数据库“测试”。它正处于恢复过程中。

当它显然不是的时候。有什么建议如何修复它吗?到目前为止发现这RECOVERY有帮助,但正如你所看到的,它没有帮助。

编辑

更改NORECOVERYRECOVERY没有帮助,因为这样我无法执行第二个命令(引发错误),并且我在特定时刻需要该日志。

编辑

我已经找到了解决方案。您需要额外的命令:

RESTORE DATABASE test
WITH RECOVERY
GO
Run Code Online (Sandbox Code Playgroud)

似乎RECOVERY在命令中被忽略RESTORE LOG,并且需要额外的命令来确认恢复已完成。不过我很感激你的帮助。

sql-server t-sql recovery

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

为什么只需在 T-SQL 中重新分配值就可以切换两个列值?

例如,以下查询按照 Microsoft SQL Server (T-SQL) 中的预期工作。

UPDATE Customer
SET ContactName = Customer.City, City = Customer.ContactName;
Run Code Online (Sandbox Code Playgroud)

我想知道为什么上面的方法有效。我原以为会Customer.City保持不变。为什么会出现这种情况?

如果您可以提供一些来源,以便我可以阅读有关这些主题的更多信息,我将不胜感激。

谢谢。

sql-server t-sql

5
推荐指数
2
解决办法
429
查看次数

IGNORE_DUP_KEY = ON 的索引过滤掉非重复记录

下面是一个脚本,可用于重现我面临的问题。基本上问题是这样的:为什么(ID1 = 6,ID2 = 7)的记录没有填充到最终的#tt2表中?我可以手动插入它,所以它不会违反 UNIQUE 约束,但它不会作为 INSERT/SELECT 的一部分进行填充。

USE [tempdb]
GO 

IF OBJECT_ID('tempdb..#t1') IS NOT NULL DROP TABLE #t1
CREATE TABLE [#t1] ([ID] INT , [V] VARCHAR(10))

INSERT INTO #t1 (ID, V) 
VALUES
(1,'A'),
(2,'B'),
(3,'B'),
(4,'C'),
(5,'E'),
(6,'E')

IF OBJECT_ID('tempdb..#t2') IS NOT NULL DROP TABLE #t2
CREATE TABLE [#t2] ([ID] INT , [V] VARCHAR(10))

INSERT INTO #t2 (ID, V) 
VALUES
(1,'A'),
(2,'B'),
(3,'C'),
(4,'C'),
(5,'D'),
(6,'E'),
(7,'E')

IF OBJECT_ID('tempdb..#tt') IS NOT NULL DROP TABLE #tt

SELECT t1.ID AS …
Run Code Online (Sandbox Code Playgroud)

sql-server t-sql unique-constraint

5
推荐指数
1
解决办法
367
查看次数