我使用的数据库应用程序中一个相当常见的模式是需要为具有“预览模式”的报表或实用程序创建存储过程。当这样的过程进行更新时,此参数指示应返回操作的结果,但该过程不应实际执行对数据库的更新。
实现这一点的一种方法是简单地if
为参数编写一个语句,并有两个完整的代码块;其中一个更新并返回数据,另一个只返回数据。但这是不可取的,因为代码重复和相对较低的置信度,即预览数据实际上是更新后会发生的情况的准确反映。
以下示例尝试利用事务保存点和变量(不受事务影响,与临时表相反)将预览模式的单个代码块用作实时更新模式。
注意:事务回滚不是一个选项,因为此过程调用本身可能嵌套在事务中。这是在 SQL Server 2012 上测试的。
CREATE TABLE dbo.user_table (a int);
GO
CREATE PROCEDURE [dbo].[PREVIEW_EXAMPLE] (
@preview char(1) = 'Y'
) AS
CREATE TABLE #dataset_to_return (a int);
BEGIN TRANSACTION; -- preview mode required infrastructure
DECLARE @output_to_return TABLE (a int);
SAVE TRANSACTION savepoint;
-- do stuff here
INSERT INTO dbo.user_table (a)
OUTPUT inserted.a INTO @output_to_return (a)
VALUES (42);
-- catch preview mode
IF @preview = 'Y'
ROLLBACK TRANSACTION savepoint;
-- save output to temp table …
Run Code Online (Sandbox Code Playgroud) 我希望能够轻松检查查询中提供的表中不存在哪些唯一标识符。
为了更好地解释,这是我现在要做的,以检查表中不存在列表“1、2、3、4”的哪些 ID:
SELECT * FROM dbo."TABLE" WHERE "ID" IN ('1','2','3','4')
,假设该表不包含 ID 为 2 的行。#N/A
都在表中没有出现的值上。我认为必须有更好的方法来做到这一点。理想情况下,我正在寻找类似的东西
要检查的列表 -> 查询要检查的表 -> 不在表中的列表成员
TL;DR:当通过解析为 IPv6 环回 ( ::1
)的名称连接到我的 SQL Server Docker 容器时,SMO 调用真的很慢。使用时127.0.0.1
,它们很快。
我正在尝试学习如何使用 Docker 映像microsoft/mssql-server-windows-developer。根据 Microsoft 的文档,此容器仅公开端口 1433 TCP。
docker run -d -p 1433:1433 -e sa_password=Passw0rd! -e ACCEPT_EULA=Y -v C:\dockerdb:C:\dockerdb microsoft/mssql-server-windows-developer
Run Code Online (Sandbox Code Playgroud)
我在 Windows 10 上运行容器,并已成功启动它,使用 SQL Server 身份验证进行身份验证,并在 Windows 主机上使用 sqlcmd 和 SSMS 17.4(连接到本地主机或“.”)和 SQL 操作对实例运行查询隔壁 Mac 上的 Studio 通过 IP 连接。以这种方式运行查询时,我看不到明显的性能问题。
在 SSMS 中,我也可以浏览对象资源管理器,但是如果我尝试从对象资源管理器中的对象的右键单击菜单中执行某些操作,例如打开实例参数窗口或附加数据库,SSMS 不会显示大约 5 次响应-10 分钟,此时它要么显示我要求的窗口,要么显示以下错误消息:
我还尝试使用 SMO Scripter object 对该实例执行一些PowerShell 脚本,并查看相同类型的行为。PS 脚本循环遍历数据库中的对象并将它们编写到文件中,虽然它可以相对较快地收集对象列表,但每个单独的对象需要 5-10 分钟来编写脚本 — 太慢而无法使用。
我有一种预感,单个暴露的端口是不够的,SMO 和 …
我正在尝试编写一个查询,当连接表 B 中的列包含表 A 中单个匹配行的多个不同值时,该查询从表 A 中返回一行。(A -> B 是 1 -> 多关系。)我构建了在上下文中演示这一点的 SQL 小提琴:http : //sqlfiddle.com/#!6/83952/1
在这个小提琴中,表格的design
列perf_ticket_type
对于每个ticket_type
具有相同的 都应该是相同的perf_id
,但我试图只选择它没有的实例。因此,对于perf_id
3,design
我当前使用的查询返回了不止一个唯一值。
我想我的结果是两列performance
的表只对perf_id
3的基础上的多重价值design
为perf_id
所加入的表。
过去我一直对 GROUP BY 的理解感到沮丧,所以我不确定我是否可以在这里做一些不同的事情来获得我想要的结果。此刻,我想我可以选择什么我都在拨弄到一个临时表,然后做另一个选择上是有GROUP BY perf_id HAVING COUNT(*) > 1
得到我想要的东西(按其中列包含在一个以上的记录相同的数据选择行)但这似乎是一个额外的步骤。
考虑以下:
CREATE PROCEDURE dbo.usp_trantest AS
SELECT @@TRANCOUNT as trancount;
GO
Run Code Online (Sandbox Code Playgroud)
当我usp_trantest
从 SSMS 中手动调用时,trancount 为 0。如果我运行包含查询相同存储过程的数据集的 SSRS 报告,则 trancount 记录为 1。
执行 SSRS 方法的 T-SQL 跟踪显示存储过程调用的跟踪事件,该事件与我从 SSMS 所做的相同。
是否有一些行为可以根据 SSRS 上下文而改变?比如,为动态 sql 调用或其他东西打开一个隐式事务,或者 SSRS 在 T-SQL 之外创建一个事务上下文?
在某人(谢谢,陌生人!)的现已删除的答案中,建议 SSRS 报告的数据集可能已选中“处理查询时使用单个事务”。原来如此!
我做了一些进一步的测试,在未选中此设置的@@TRANCOUNT
情况下,无论是在 SSMS 中运行还是从 SSRS 报告中运行都是一样的。
因此,我们似乎可以得出结论,此数据源设置确实会导致 SSRS 报告在运行查询之前在数据库上创建事务上下文。由于这个额外的事务没有出现在 T-SQL 跟踪中,我们可以假设它是使用 API 方法而不是 T-SQL 语句打开的。
我正在处理一个 SQL 查询,它根据过去的购买(行业是场地票务)将客户历史记录放在一起。报告将是大的,类似于 80-90 列,输出 CSV 中的每个事件或每个记录的事件类别一列。
数据库结构要求我使用嵌套的 select 语句将必要的数据放入每条记录的列中——每列包含该类型事件的票证数量。我在理论上知道如何执行此操作,但是每个嵌入的 select 语句都非常大,以至于完整报告将突破我的数据库界面上的 8,000 个字符限制。这些语句之一如下所示:
(select count (*)
FROM
guest ig, event2 e, eventseat es, "order" o
WHERE ig.guestid = g.guestid
and ig.guestid = o.guestid
and o.orderid = es.orderid
and e.eventid = es.eventid
and e.incometype = 'T'
and e.eventtype in ('SS', 'BMF')
and es.status in ('2','4')
and es.price <> '0.00'
and es.price <> '5.00'
and e.year = '2010' <-- THESE LINES ARE THE ONLY ONES THAT
and e.run in ('SS-DANCE') <-- …
Run Code Online (Sandbox Code Playgroud)