不久前,我问了一个关于如何使开始对话框和发送更灵活的问题,以便它可以嵌入到将 to、from 参数作为 sysname 变量的过程中。
多个发起者将使用的服务代理程序开始对话对话..如何将参数传递给它
然而,正如 Rusanu 在回答中提到的,同样的技术不能用于接收的 From 子句。
实际上它会起作用。大多数 SSB 动词都接受参数作为参数(当然,RECEIVE 的队列名称除外)。参数的类型为 sysname ...
实际上发送方已经完成,我现在试图以同样的方式使接收变得灵活,例如:
CREATE PROCEDURE QueueReceive
@myTargetQueue SYSNAME
@cg UNIQUEIDENTIFIER OUTPUT
@ch UNIQUEIDENTIFIER OUTPUT
@msg XML OUTPUT
as
BEGIN TRANSACTION;
WAITFOR
( RECEIVE TOP(1)
@cg = conversation_group_id,
@msg = cast(message_body as XML),
@ch= conversation_handle
FROM @myTargetQueue
), TIMEOUT 3000;
COMMIT
...
Run Code Online (Sandbox Code Playgroud)
似乎不能在 RECEIVE 的 from 子句中使用 sysname 类型的变量?如果我必须在动态 SQL 中执行此操作,我将如何从接收函数的动态 sql 执行中返回所有变量、conversation_group_id、conversation_handle 等?有没有更好的技术来完成同样的事情?
谢谢你。
修复/更新到目前为止:我正在创建一堆 IF 子句,具体取决于传递的参数是什么,它只会执行不同的整个接收语句。它效率不高,因为我每次添加新 QUEUE 时都必须更改过程代码,但我想现在可以了...
PostgreSQL 实现了execute ... using将参数传递给动态 SQL的选项,据我所知,这个功能是在 8.4 版中引入的。我们使用的是Greenplum,它是从8.2 版的PostgreSQL 分叉出来的,所以它没有这个特性。
有没有其他方法可以在 Greenplum 或 PostgreSQL 8.2 中做同样的事情?
我在 64 位 Windows 7 上运行 PostgreSQL 9.3.5。
我的数据每季度到达,在多个表 ( table1, ..., tableN) 中,这些表在周期内通过基于关键标识符的跨表约束进行链接。在其他列中,每个表都具有随时间持续存在的标识符:pfi-持久特征标识符和ufi-通用特征标识符。
pfi每个表都是唯一的(非常罕见的是table1.pfi = table2.pfi.
ufi在所有表和所有时间都是唯一的。它不是行数据的散列,但您可以这样认为。
每个时期,在每个表中,一些新的pfi产生,一些旧pfi的退役。一些pfi改变属性。ufi跟踪给定(行)的任何属性的任何更改pfi,因此为它获取更改的(和新的)行table1只是一个问题:
-- 1st query
select a.*
into vm201512.property_d
from vm201512.property a
where not exists (select 1 from vm201412.property where ufi = a.ufi);
Run Code Online (Sandbox Code Playgroud)
这将选择pfi在至少一列中是新的 (new ) 或更改的所有行。
每个表的大约 96% 在各个方面都保持不变。因此,在分析跨周期变化时,我构建了一个仅包含更改数据和新数据的表。这将表大小从 ~3.5m 行减少到 …
我有一个从 .net 应用程序生成的查询,参数是 linq 参数。我用来调整查询的过程如下。
查询的形式是
exec sp_executesql N'SELECT
[Extent1].[Id] AS [Id],
[Extent1].[GroupId] AS [GroupId],
[Extent1].[Agency] AS [Agency],
[Extent1].[Group] AS [Group],
[Extent1].[Claim] AS [Claim],
[Extent1].[StartDate] AS [StartDate],
[Extent1].[ExpireDate] AS [ExpireDate],
[Extent1].[IsActive] AS [IsActive]
FROM [dbo].[Permissions] AS [Extent1]
WHERE ([Extent1].[GroupId] = @p__linq__0) AND (([Extent1].[ExpireDate] IS NULL)
OR ([Extent1].[ExpireDate] > @p__linq__1)) AND ([Extent1].[IsActive] <> 1)',
N'@p__linq__0 int,@p__linq__1 datetime2(7)',
@p__linq__0=15,@p__linq__1='2017-05-10 00:00:00'
Run Code Online (Sandbox Code Playgroud)这只是一个示例查询。实际查询要大得多,并且包括许多涉及多个视图和表等的连接。
我的问题是:
sp_executesql并将过滤器值应用于查询时,它会在不到 1 秒的时间内运行。我知道由于这些值是硬编码到查询中的,所以它会更快,但为什么执行时间会有这么大的差异?两者的执行计划也不同:
我是在这台服务器上工作的唯一用户,我在两种情况下都执行相同的参数。我已经申请OPTION(RECOMPILE) …
performance sql-server dynamic-sql execution-plan query-performance
我正在尝试获取有关数据库中数据的信息。我在几个表中有几列输入“TEXT”。我想执行一个查询,该查询将创建如下所示的结果:
|table_name|column_name|max_length|
-----------------------------------
|my_table |name |35 |
Run Code Online (Sandbox Code Playgroud)
我有查询来获取所有表和列:
SELECT table_name, column_name FROM information_schema.columns
WHERE table_schema = 'public' AND data_type = 'text'
ORDER BY table_name
Run Code Online (Sandbox Code Playgroud)
但我现在不知道如何遍历每个表和列以获得每列的最大长度。我确实有一个查询来获取特定列和表的最大长度:
SELECT 'my_table', 'name', MAX(LENGTH(name)) FROM my_table
Run Code Online (Sandbox Code Playgroud)
如何进行查询,根据查询结果动态获取最大长度以获取所有表和列?
如果本地临时表仅对当前会话可用,并且 sp_ExecuteSql 创建一个新会话来执行传递给它的动态 SQL 字符串,那么该动态 SQL 查询如何访问在执行 sp_ExecuteSql 的会话中创建的临时表。
换句话说,为什么这样做:
SELECT 1 AS TestColumn
INTO #TestTempTable
DECLARE @DS NVARCHAR(MAX) = 'SELECT * FROM #TestTempTable'
EXEC sp_EXECUTESQL @DS
Run Code Online (Sandbox Code Playgroud)
结果:
我之所以不能做相反的事情(在动态 SQL 中创建临时表,然后在执行会话中的动态 SQL 查询之外访问它),我的理解是因为 sp_ExecuteSql 在新会话下执行。
sql-server dynamic-sql session temporary-tables sql-server-2016
是否有发布的明确列表显示在调用 sp_executesql 时可以和不能参数化的内容。
例如,谓词可以,表名不能。TOP 中的行数可以:
exec sp_executesql @stmt =
N'SELECT TOP(@n) a, b
FROM (VALUES(1,2)) v(a,b)',
@params = N'@n int',
@n = 10
Run Code Online (Sandbox Code Playgroud)
MAXDOP 不能:
exec sp_executesql @stmt =
N'SELECT TOP(10) a, b
FROM (VALUES(1,2)) v(a,b)
OPTION (MAXDOP @n)',
@params = N'@n int',
@n = 10
Run Code Online (Sandbox Code Playgroud)
消息 102,级别 15,状态 1,第 8 行“@n”附近的语法不正确。
我想还有更多的例子说明什么有效,什么无效。我正在寻找一个权威列表来消除反复试验。
我不喜欢触发器和动态 sql,但是,我正在使用的东西需要两者。
CREATE TRIGGER [dbo].[GenerateDynamicFormItemViews] ON [dbo].[tblFormItems] AFTER INSERT, UPDATE
AS
BEGIN
SET NOCOUNT ON;
DECLARE @DatabaseName NVARCHAR(100)
DECLARE @FormItemID INT
DECLARE db_cursor CURSOR FOR
SELECT SourceID,FormItemID from Inserted
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO @DatabaseName, @FormItemID
WHILE @@FETCH_STATUS = 0
BEGIN
BEGIN TRY
EXEC spAddEditFormItemView @FormItemID, @DatabaseName WITH RESULT SETS NONE
END TRY
BEGIN CATCH
INSERT INTO AdminErrorLog(SourceID, ErrorNumber, ErrorState, ErrorSeverity, ErrorProcedure, ErrorLine, ErrorMessage, ErrorDateTime)
SELECT @DatabaseName, ERROR_NUMBER(), ERROR_STATE(), ERROR_SEVERITY(), ERROR_PROCEDURE(), ERROR_LINE(), ERROR_MESSAGE(), GETDATE()
END CATCH
FETCH NEXT …Run Code Online (Sandbox Code Playgroud) 我的数据库中有一个表,其中存储了成功和失败的登录尝试。我正在创建一个存储过程,允许我们删除超过 X 天的记录。到目前为止一切顺利,但我想把它提高一个(或两个)等级,并允许我们指定是否删除关于 [Success] 列是真、假还是两者兼而有之的记录。不过,我在连接需要执行的脚本时遇到了一些问题。
这是我到目前为止所做的:
-- CREATE PROCEDURE [dbo].[sp_delete_log_attempts]
DECLARE @backDays INT = 1 -- Default to 30 days (one test finishes)
DECLARE @successArg BIT = NULL -- default to both true and false success logins
DECLARE @successAnd VARCHAR(50)
DECLARE @query VARCHAR(MAX)
SET @successAnd = CASE
WHEN @successArg = 'true' THEN
'AND [Success] = ''true'''
WHEN @successArg = 'false' THEN
'AND [Success] = ''false'''
ELSE
'AND [Success] = ''true'' OR [Success] = ''false'''
END
PRINT @successAnd -- just for …Run Code Online (Sandbox Code Playgroud) dynamic-sql ×10
sql-server ×5
postgresql ×2
greenplum ×1
parameter ×1
performance ×1
plpgsql ×1
session ×1
t-sql ×1
trigger ×1