标签: dynamic-sql

sp_ExecuteSQL、性能和表变量

有没有人能够解释我在 SQL Profiler 中看到的一些行为?采取以下两批:

exec sp_executesql N'
    declare @t table (
        x int
    )

    insert into @t (x) select top 10 number from dbo.gennumbers

    select * from @t
    union
    select * from @t
'

exec sp_executesql N'
    select top 10 number from dbo.gennumbers
    union
    select top 10 number from dbo.gennumbers
'
Run Code Online (Sandbox Code Playgroud)

(这是我正在进行的一些重构的简化;实际上,临时表是通过在最终查询中重用的 CTE 填充的,因此通过缓存数据来减轻 SQL Server 需要执行的重复工作量)。

在这个例子中,GenNumbers 只是一个数字表,只有一个列,只包含一个连续运行的数字 - 没什么特别的。

在探查器中,我得到以下结果:

第 1 批,带有临时表:

事件 TextData 读取
SP:StmtCompleted INSERT INTO(...) 27
SP:StmtCompleted SELECT * FROM ... 6
SQL:StmtCompleted exec …

sql-server dynamic-sql sql-server-2008-r2

6
推荐指数
1
解决办法
2013
查看次数

使用动态 SQL 在不同的数据库中创建视图

作为一个更大项目的一部分,我试图在 SQL Server 实例中的每个数据库上创建一个新视图。

我创建了一个存储过程,其中包括通过游标循环遍历实例中的数据库,然后尝试使用sp_executesql. 不幸的是,我试图在其上创建视图的数据库中不存在存储过程。所以我试图让 sql server 使用该数据库,然后运行创建视图脚本。当我运行它时,我收到错误

'CREATE VIEW' 必须是查询批处理中的第一个语句。

关于我如何做到这一点的任何想法?这是sp_executesql程序的一部分。

declare @DB VARCHAR(50)
declare @SQL NVARCHAR(max)
set @DB = '[dbname]'

SET @SQL =  N'USE ' + @DB + N' CREATE VIEW vNonhiddenCategories 
AS
SELECT categories.categoryid
FROM categories
--WHERE ... irrelevant remainder of view code ...
'
execute sp_executesql @SQL
Run Code Online (Sandbox Code Playgroud)

sql-server-2008 sql-server dynamic-sql t-sql

6
推荐指数
1
解决办法
9934
查看次数

跨多个模式查询,直到执行时间未知

我有多个需要查询的模式。模式是事先未知的,例如:

  • U111
  • U222
  • U333

我需要从这些模式中的每一个中的特定表中选择这三个模式。我可以将这个查询放在这三个模式中吗?如果是这样,我如何查询它们?请记住,我不会提前知道模式名称,因此需要动态构建它们。

schema postgresql dynamic-sql plpgsql

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

更新引用时删除行

假设我有一个person带有 id 和其他一些列的表。其他表person使用ON UPDATE CASCADE. 例如:

CREATE TABLE person (id int PRIMARY KEY);
CREATE TABLE sale (id int PRIMARY KEY,
    person_id int REFERENCES person(id) ON UPDATE CASCADE);
Run Code Online (Sandbox Code Playgroud)

现在,我想要做的是:从 person 表中删除重复的条目,修复referencessale引用。例如,使用此数据:

INSERT INTO person values (1), (2), (3);
INSERT INTO sale VALUES (11, 1), (12, 2), (13, 3);
Run Code Online (Sandbox Code Playgroud)

Person12实际上是一样的,所以他们应该被“合并”。通过合并我的意思是不包括人2在更新的人引用1sale表。

由于ON UPDATE CASCADE表上有一个引用person,我想知道是否有某种方法可以在不必手动更新sale表的情况下,在删除人的同时导致级联更新2

我在这里试图实现的是避免使用专用程序来更新引用,因为引用表的数量很可能会增加,需要在此过程中进行维护(并且已经相当大了)。

postgresql delete dynamic-sql referential-integrity update

6
推荐指数
1
解决办法
3807
查看次数

检查字符类型列中是否存在空字符串

我有一个应用程序(作为其逻辑的一部分)在插入数据库之前修剪字符串并用 NULL 替换空字符串。我想确保强制执行的一种方法是在每个具有VARCHAR, TEXT(或类似)列的表上编写一个 CHECK 。

假设人们不能或不想这样做,有没有一种方法可以编写一个简单的通用 SQL 查询(从数据库的元数据中获取表名和列名)来检查数据库中是否有任何文本列包含空字符串?

postgresql database-design dynamic-sql plpgsql postgresql-9.1

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

复制具有单独序列的连续列的表

在创建列管理工具时,我遇到了在 PostgreSQL 中快速复制表的需要,因此我不会使用非测试表来测试新工具。为了有效地测试我最终打算在表上使用的新列工具,parts我创建了这个新工具来复制parts,这样我最终会得到一个parts1表。当我以为我终于解决了所有问题时,当列工具删除表时,我遇到了以下错误:

错误:无法删除表部分,因为其他对象依赖于它详细信息:表 parts1 列 id 的默认值取决于序列 parts_id_seq1

我花了一天的大部分时间来研究这个解决方案,所以简而言之,我可以简单地使用字符串函数来重命名变量以将表与表SEQUENCE_NAME分离,还是这是一个比这更复杂的问题?这是查询:partsparts

DO $$
  DECLARE
    SEQUENCE_NAME VARCHAR;
  BEGIN
    SELECT s.relname INTO SEQUENCE_NAME
    FROM pg_class AS s JOIN pg_depend d ON d.objid = s.oid 
    INNER JOIN pg_class AS t ON d.objid = s.oid AND d.refobjid = t.oid 
    INNER JOIN pg_attribute AS a ON (d.refobjid, d.refobjsubid) = (a.attrelid, a.attnum) 
    INNER JOIN pg_namespace AS n ON n.oid = s.relnamespace 
    WHERE s.relkind = 'S' …
Run Code Online (Sandbox Code Playgroud)

postgresql database-design primary-key sequence dynamic-sql

6
推荐指数
1
解决办法
7642
查看次数

从 plpgsql 中的文本动态转换

我的数据库中的许多表共享一个公共布局,特别是它们有一个serial以关系名称命名的主键。从 Web 应用程序中更新这些表通常涉及以下形式的查询:

UPDATE table SET attribute = x WHERE table_id = y
Run Code Online (Sandbox Code Playgroud)

这很常见,以至于我有一个执行此任务的存储过程:

CREATE OR REPLACE FUNCTION setvalue(
    relname text,
    row_id integer,
    colname text,
    newvalue text)
RETURNS void AS
$BODY$
BEGIN
  EXECUTE format('UPDATE %I SET %I = $1 WHERE %I = $2', relname, colname, relname || '_id', colname) USING row_id;
END;
$BODY$
LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)

不幸的是,这不适用于非文本类型。例如,更新一date列给出ERROR: column ... is of type date but expression is of type text. 假设文本是预期类型的​​有效文字表示,是否有一种安全的方法让 DBMS 找出正确的类型并做正确的事情?

postgresql dynamic-sql plpgsql

6
推荐指数
1
解决办法
836
查看次数

创建一个动态联合新表的视图

我有一个名为的数据库DDOS_WAF_REPORT,其中包含多个名称格式dbo.DDOS_WAF_ACCOUNT_######(5 位或 6 位 ID 号)的表。

所有表都具有完全相同的结构(列名和类型)。我想UNION ALL一起为他们创建一个视图。此外,还会有相同类型的新表稍后添加到数据库中,因此我需要视图能够“遍历”数据库中的所有现有表并添加它们(添加或创建视图)划痕)。

我已经用硬编码的表名创建了一个简单的视图,但是我很难解决动态创建视图的问题。我正在使用 SQL Server 2012。

添加的表是针对每个帐户的 API 运行的外部脚本的结果,因此我无法避免数据库中有多个表。我假设我可能需要编写一些脚本代码来实际运行并检查新表名,但我想看一些例子来弄清楚如何做到这一点。

sql-server dynamic-sql view sql-server-2012

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

在 ORDER BY 中使用 CASE .. END 有意义吗?

类似SELECT * FROM t ORDER BY case when _parameter='a' then column_a end, case when _parameter='b' then column_b end的查询是可能的,但是:这是一个好习惯吗?

在查询的 WHERE 部分使用参数是很常见的,在 SELECT 部分有一些计算列,但参数化 ORDER BY 子句并不常见。

假设我们有一个列出二手车的应用程序 (à la CraigsList)。汽车列表可以按价格或颜色排序。我们有一个函数,给定一定数量的参数(比如价格范围、颜色和排序标准),它会返回一组带有结果的记录。

为了具体起见,让我们假设cars都在下表中:

CREATE TABLE cars
(
  car_id serial NOT NULL PRIMARY KEY,  /* arbitrary anonymous key */
  make text NOT NULL,       /* unnormalized, for the sake of simplicity */
  model text NOT NULL,      /* unnormalized, for the sake of simplicity */
  year integer,             /* may …
Run Code Online (Sandbox Code Playgroud)

postgresql order-by dynamic-sql functions postgresql-9.6

6
推荐指数
1
解决办法
9741
查看次数

如何使用 format() 函数引用限定表名?

format我在使用下面示例中的函数正确引用表名时遇到一些问题。

CREATE OR REPLACE FUNCTION copy_table(_source_tbl regclass, _target_tbl text)
 RETURNS bool AS $func$
DECLARE query_str text; 
BEGIN
  query_str = format($fmt$ DROP TABLE IF EXISTS %1$I; CREATE TABLE %1$I AS (TABLE %s); $fmt$, _target_tbl, _source_tbl);
  EXECUTE query_str;
  RAISE NOTICE '%', query_str;
 RETURN True;
END $func$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)

我的困境是我想引用输入表名称_target_tbl作为标识符(以避免 SQL 注入)。但是,给定完整的表名称ex.test1,这会导致架构部分ex.被视为表名称的一部分,并public."ex.test1"在默认public.架构中创建表,如下所示。

我应该如何在此处正确引用/格式化标识符?

=> SELECT copy_table('ex.test', 'ex.test1');
NOTICE:  table "ex.test1" does not exist, skipping
NOTICE:   DROP TABLE IF EXISTS "ex.test1"; CREATE TABLE …
Run Code Online (Sandbox Code Playgroud)

postgresql dynamic-sql plpgsql postgresql-10

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