是否可以在存储过程中使用动态生成的SQL在MySQL中创建触发器?我正在通过准备语句在我的过程中执行其他动态构造的查询,但是当我尝试相同的方法来创建触发器时,我得到以下错误:
错误代码:1295尚未在准备好的语句协议中支持此命令
从Bug#31625开始,PREPARED STATEMENT语法不允许创建TRIGGERS我看到自2007年以来其他人一直抱怨同样的事情.
这个问题有解决方法吗?是否有另一种使用动态SQL创建触发器的方法?
基本上我要做的是动态创建触发器,用于记录各种不同表上插入的审计数据.我在*audit_tables*表中列出了我想要审核的表.下面的精简过程迭代该表中的条目并尝试创建触发器.
drop procedure if exists curtest;
delimiter |
create procedure curtest()
BEGIN
DECLARE done INT DEFAULT 0;
declare tn varchar(16);
declare cur cursor for select table_name from audit_tables;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
OPEN cur;
read_loop: LOOP
fetch cur into tn;
if done then
leave read_loop;
end if;
/* Create the BEFORE INSERT trigger */
set @sql = concat('CREATE TRIGGER audit_', …Run Code Online (Sandbox Code Playgroud) 我有一个SQL脚本需要删除几个约束并在最后恢复它们,但约束名称是自动生成的,并且每次运行脚本时都会有所不同.
我知道如何从表名中获取约束名称,但似乎不可能在drop语句中使用此信息.
select conname from pg_constraint where
conrelid = (select oid from pg_class where relname='table name')
and confrelid = (select oid from pg_class where relname='reference table');
Run Code Online (Sandbox Code Playgroud)
alter table something drop constraint (some subquery) 是语法错误.
理想情况下,我想得到约束名称并将其存储在一个变量中,但似乎Postgres不支持它,我不能使它与psql一起使用\set.
这甚至可能吗?
我有一个类似于以下的表:
CREATE TABLE stats (
name character varying(15),
q001001 numeric(9,0),
q001002 numeric(9,0),
q001003 numeric(9,0),
q001004 numeric(9,0),
q001005 numeric(9,0)
)
Run Code Online (Sandbox Code Playgroud)
我需要在这个表中查询各个字段的总和,如下所示:
SELECT sum(q001001) as total001,
sum(q001002) as total002,
sum(q001005) as total005,
FROM stats;
Run Code Online (Sandbox Code Playgroud)
这会产生一行数据和三列数据.
但是,出于报告目的,我需要以相反的方式列出结果.我需要三行和一列(好吧,实际上是两个,第一个是总和的字段),如下所示:
FieldName | SUM
----------+-------
q001001 | 12345
q001002 | 5432
q001005 | 986
Run Code Online (Sandbox Code Playgroud)
我想使用这样的一些SQL,其中field_name(来自stats表中字段名称的查找表)用于子查询:
select l.field_name, (select sum(l.field_name) from stats)
from stats_field_names_lookup as l
where l.field_name in ('Q001001', 'Q001002', 'Q001005');
Run Code Online (Sandbox Code Playgroud)
这里的想法是,sum(l.field_name)将替换为相关的实际字段名称,对于WHERE子句中的每个名称,然后进行评估以提供正确的求和结果值.但是,这会因以下错误而失败:
函数和(字符变化)不存在
因为值有文字/字符.如何将该字符值转换为要正确计算的未加引号的字符串?
这个SQL有效.但是,当然,每个都给出相同的和值field_name,因为它q001001在这里是硬编码的.
select l.field_name, …Run Code Online (Sandbox Code Playgroud) 我想更新表中的列,stats其中特定列是一个参数,然后返回该列的更新值[只有1行]:
CREATE FUNCTION grow(col varchar) RETURNS integer AS $$
DECLARE
tmp int;
BEGIN
tmp := (EXECUTE format(
'UPDATE stats SET %I = %I + 1
RETURNING %I',
col, col, col
)
);
RETURN tmp;
END;
Run Code Online (Sandbox Code Playgroud)
总的来说,我甚至不确定这是否是我想做的最佳方式,任何建议都将不胜感激!
[更新:使用 SQL Server 2005]
您好,我想要做的是使用逗号分隔的值 (ids) 列表查询我的存储过程以检索数据行。
我收到的问题是转换错误:
Conversion failed when converting the varchar value ' +
@PassedInIDs + ' to data type int.
Run Code Online (Sandbox Code Playgroud)
我的 where 子句和错误中的语句是:
...
AND (database.ID IN (' + @PassedInIDs + '))
Run Code Online (Sandbox Code Playgroud)
注意:database.ID是int类型。
我正在关注这篇文章:
http://www.sql-server-helper.com/functions/comma-delimited-to-table.aspx
但由于错误而没有完成。
在我的执行脚本中,我有:
...
@PassedInIDs= '1,5'
Run Code Online (Sandbox Code Playgroud)
我在这里做错了什么吗?感谢您的帮助。
我正在使用Sql Server 2008并且有一个在内部使用sp_executesql的proc.通过ASP.NET执行proc时,我一直收到以下错误:
对象'MyTable',数据库'MyDatabase',架构'dbo'上的SELECT权限被拒绝.
我已经对此做了大量研究,大多数人都指出我需要在动态查询读取的基础表上授予select权限.好吧,我已经完成了这个,它似乎仍然无法正常工作:
select object_name(major_id) as object,
user_name(grantee_principal_id) as grantee,
user_name(grantor_principal_id) as grantor,
permission_name,
state_desc
from sys.database_permissions
where major_id = object_id('User') and
class = 1
Run Code Online (Sandbox Code Playgroud)
Results: MyTable public dbo SELECT GRANT MyTable guest dbo SELECT GRANT MyTable myuser dbo SELECT GRANT MyTable NT AUTHORITY\NETWORK SERVICE dbo SELECT GRANT
正如你所看到的,我试图在基础表上授予select,这已经过度了.我甚至重新编写了我的proc,以便它只在动态sql中引用MyTable.我甚至已经授予所有上述用户"proc"执行权限...没有运气.
上面的"myuser"是web.config中我的connectionstring中的用户名.
我在这里错过了什么吗?
谢谢!戴夫
我理解,如果使用不正确,子查询对性能的影响是非常糟糕的.我有一个非常具体的场景,用户需要从表中检索过滤的记录集.将提供各种各样的过滤器,它们必须支持组合.此外,一组开发人员将定期创建新的过滤器.
我不喜欢一个增长的,单片的SQL查询与大量参数的想法.我不喜欢一堆具有相同SELECT语句和不同WHERE子句的自治SQL查询.我喜欢动态SQL查询的想法,但我不确定我应该使用什么样的结构.我可以想到4个基本选项:(如果还有更多我不知道的话,那么请不要犹豫,建议他们)
我创建了一个SQL小提琴来演示(和配置)它们:
下面是小提琴的摘录,提供我正在谈论的内容:
------------------------------------------------------------------------
--THIS IS AN EXCERPT FROM THE SQL FIDDLE -- IT IS NOT MEANT TO COMPILE--
------------------------------------------------------------------------
--
--"INNER JOIN" test
SELECT COUNT(*)
FROM
@TestTable Test0
INNER JOIN @TestTable Test1 ON Test1.ID=Test0.ID AND Test1.ID % @i = 0
INNER JOIN @TestTable Test2 ON Test2.ID=Test0.ID AND Test2.ID % @j = 0
INNER JOIN @TestTable Test3 ON Test3.ID=Test0.ID AND Test3.ID % @k = 0
--
--"FROM subqueries" test
SELECT COUNT(*) …Run Code Online (Sandbox Code Playgroud) 我想选择列名但我不知道表结构,它可能会改变所以我不能只用列名硬编码select语句.我也不想选择每一列.有没有简单的方法来做到这一点?
我的想法是这两个查询的某种组合,但我的SQL不是那么好.
SHOW COLUMNS FROM table_name;
SELECT * FROM table_name;
Run Code Online (Sandbox Code Playgroud)
我尝试使用子选择,但它没有用.似乎没有发生任何事情,我没有得到错误我没有得到任何结果
SELECT (SELECT column_name
FROM information_schema.columns
WHERE table_name ='table_name')
FROM table_name;
Run Code Online (Sandbox Code Playgroud)
也许我需要加入?..无论如何,任何帮助都会很棒,谢谢
我有一个存储过程作为SQL命令文本,它传递一个包含表名称的参数.然后proc从该表返回数据.我不能直接将表调用为OLE DB源,因为某些业务逻辑需要发生在proc中的结果集中.在SQL 2008中,这很好用.在升级的2012软件包中,我得到"无法确定元数据,因为...包含动态SQL.请考虑使用WITH RESULT SETS子句来明确描述结果集."
问题是我无法在proc中定义字段名称,因为作为参数传递的表名可以是不同的值,并且结果字段每次都可以不同.有人遇到这个问题还是有什么想法?我使用动态SQL尝试了各种各样的事情,使用"dm_exec_describe_first_result_set",临时表和包含WITH RESULT SETS的CTE,但它在SSIS 2012中不起作用,同样的错误.Context是许多动态SQL方法的问题.
这是我尝试的最新事情,没有运气:
DECLARE @sql VARCHAR(MAX)
SET @sql = 'SELECT * FROM ' + @dataTableName
DECLARE @listStr VARCHAR(MAX)
SELECT @listStr = COALESCE(@listStr +',','') + [name] + ' ' + system_type_name FROM sys.dm_exec_describe_first_result_set(@sql, NULL, 1)
exec('exec(''SELECT * FROM myDataTable'') WITH RESULT SETS ((' + @listStr + '))')
Run Code Online (Sandbox Code Playgroud) 问题
存储过程正在接收变量和值列表以及分隔符.此存储过程需要将它们插入表中.
--Example table
create table #tempo
(
Variable1 int,
Variable2 int,
Variable3 int
)
Run Code Online (Sandbox Code Playgroud)
这些是存储过程的参数:
declare @variableList varchar(100)
declare @valueList varchar(100)
declare @separator char(1)
set @variableList = 'Variable1#Variable2#Variable3'
set @valueList = '1111#2222#3333'
set @separator = '#'
Run Code Online (Sandbox Code Playgroud)
结果
我想要实现的是:
select * from #tempo
+---------+---------+---------+
|Variable1|Variable2|Variable3|
+---------+---------+---------+
|1111 |2222 |3333 |
+---------+---------+---------+
Run Code Online (Sandbox Code Playgroud)
一种方法
我可以使用循环并构建动态SQL,但我想避免它.除了不使用动态SQL的明显原因之外,循环结构很难维护,解释和测试也可能成为一个问题.
理想的方式
我正在考虑一种更优雅的方法,例如使用string_split或coalesce等.但是如果不使用动态SQL或循环,就无法找到方法.
dynamic-sql ×10
sql ×5
postgresql ×3
sql-server ×3
mysql ×2
plpgsql ×2
asp.net ×1
delimited ×1
delimiter ×1
loops ×1
metadata ×1
permissions ×1
psql ×1
ssis ×1
subquery ×1
t-sql ×1
triggers ×1
unpivot ×1