使用 Postgres pl/pgsql,我尝试使用动态 EXECUTE 命令创建一个表,例如:
...
DECLARE
tblVar varchar := "myTable";
BEGIN
EXECUTE 'CREATE TABLE $1 (
foo integer NOT NULL,
bar varchar NOT NULL)'
USING _tblVar;
...
Run Code Online (Sandbox Code Playgroud)
但是,我继续收到错误消息
错误:“$1”处或附近的语法错误
如果我不使用$1令牌,而是编写字符串,myTable它就可以正常工作。
对 CREATE 调用使用动态语句是否有限制?
我已经将动态 SQL 用于许多任务并不断遇到相同的问题:打印动态 T-SQL 语句中使用的变量的值。
例如:
Declare @SQL nvarchar(max), @Params nvarchar(max), @DebugMode bit, @Foobar int
select @DebugMode=1,@Foobar=364556423
set @SQL='Select @Foobar'
set @Params=N'@Foobar int'
if @DebugMode=1 print @SQL
exec sp_executeSQL @SQL,@Params
,@Foobar=@Foobar
Run Code Online (Sandbox Code Playgroud)
上面代码的打印结果就是“Select @Foobar”。有没有办法动态打印正在执行的sql的值和变量名?或者在打印时,用实际值替换参数以便 SQL 可以重新运行?
我曾尝试创建一两个函数来完成类似的事情,但涉及数据类型转换、模式匹配截断问题和非动态解决方案。我很好奇其他开发人员如何在不手动打印每个变量的情况下解决这个问题。
简单的背景故事,我们正在与拥有调查系统的外部供应商合作。系统不一定设计得最好,因为当您创建新调查并且系统创建新表时,即:
Tables
____
Library_1 -- table for Survey 1
SurveyId int
InstanceId int
Q_1 varchar(50)
Library_2 -- table for Survey 2
SurveyId int
InstanceId int
Q_2 int
Q_3 int
Q_4 varchar(255)
Run Code Online (Sandbox Code Playgroud)
这些表用所生成的SurveyId在名称的末尾(Library_)和问题列与所产生的QuestionId在它(结束Q_)。 澄清一下,问题存储在单独的表中,因此虽然问题 id 是连续的,但对于每个调查,它们不会从 1 开始。问题列将基于表中分配给它们的 id。
查询似乎很简单,但我们需要从所有调查表中提取数据以发送到另一个系统,这就是问题所在。由于前台添加新调查时会自动创建表 -最终应用程序,其他系统无法处理这种类型的结构。他们需要数据一致才能消费。
因此,我的任务是编写一个存储过程,该过程将从所有调查表中提取数据并将其放置在以下格式中:
SurveyId InstanceId QNumber Response
________ __________ _______ ________
1 1 1 great
1 2 1 the best
2 9 2 10
3 50 50 test
Run Code Online (Sandbox Code Playgroud)
通过让所有表格的数据采用相同的格式,无论存在多少调查表格和问题,任何人都可以使用这些数据。
我写了一个似乎可以工作的存储过程,但我想知道我是否遗漏了什么,或者是否有更好的方法来处理这种情况。
我的代码:
declare @sql varchar(max) …Run Code Online (Sandbox Code Playgroud) 我已授予用户执行使用动态 SQL 的存储过程的权限。但是当他试图执行它时,他得到了错误:
对象“[表名]”、数据库“[数据库名]”、架构“dbo”的 SELECT 权限被拒绝。
用户是否需要被授予存储过程使用的任何表的权限?那对我来说真的没有任何意义。
我有 100 多个名为 public.test_* 的表
我怎样才能轻松地一次GRANT ALL访问所有这些表的用户测试?
我试过:
GRANT ALL ON TABLE public.test_* TO test;
Run Code Online (Sandbox Code Playgroud)
但它不起作用......
如果目标数据库中存在表,我正在尝试签入存储过程。如果没有,我将使用源数据库中的 information_schema 表创建表。但是,当我使用 sp_execute 尝试恢复表是否存在时,我收到错误过程需要“int”类型的参数“@handle”。
我没有使用@handle 参数。有人能告诉我这个错误是什么意思以及为什么我会收到它吗?我的代码的相关部分如下。
DECLARE @SQL NVARCHAR(MAX),
@Parameters NVARCHAR(4000),
@TableNotExists INT,
@SourceTable NVARCHAR(200),
@DestDB NVARCHAR(200)
BEGIN
SET @SourceTable = 'table'
SET @DestDB = 'database'
SET @Parameters = N'@SourceTableIN NVARCHAR(200), @TableNotExistsOut INT OUTPUT'
SET @SQL = N'USE [' + @DestDB + '] IF NOT EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = ''BASE TABLE'' AND TABLE_NAME = @SourceTableIN)
BEGIN SET @TableNotExistOUT = 1 END'
EXEC sp_Execute @SQL, @Parameters, @SourceTableIN = @SourceTable, @TableNotExistsOUt = @TableNotExists OUTPUT
END
Run Code Online (Sandbox Code Playgroud) 我想知道这在 Postgres 中是否可行:
最好用一个人为的例子来解释:
create or replace function test_function(filter_param1 varchar default null
, filter_param2 varchar default null)
returns integer as
$$
declare
stmt text;
args varchar[];
wher varchar[];
retid integer;
begin
if filter_param1 is not null then
array_append(args, filter_param1);
array_append(wher, 'parameter_name = $1');
end if;
if filter_param2 is not null then
array_append(args, filter_param2);
array_append(wher, 'parameter_name = $2');
end if;
stmt := 'select id from mytable where ' || array_to_string(wher, ' or ');
execute stmt into retid using args;
return retid; …Run Code Online (Sandbox Code Playgroud) 我有一个涉及在多个数据库之间执行各种命令的过程 - 但是,当我使用动态 SQL 通过“使用 @var”更改数据库时,它实际上并没有更改数据库。
在 [test_db] 中执行:
declare @currentDB varchar(max)
declare @sql varchar(max)
set @currentDB = DB_NAME()
set @sql = 'use [' + @currentDB +']'
use master
exec(@sql)
select DB_NAME()
Run Code Online (Sandbox Code Playgroud)
返回 [Master] 作为当前数据库名称 - 如果我将其use [test_db]作为命令而不是动态放置,则它返回正确的名称。
有没有办法做到这一点,可以在数据库之间正确切换?
最近我们对我们的数据库使用了一个 sql 代码审查工具。建议使用SP_EXECUTESQL代替EXEC.
我知道SP_EXECUTESQL可以帮助我们避免 sql 注入。使用EXECvs时性能有什么不同吗SP_EXECUTESQL?
performance sql-server dynamic-sql t-sql exec query-performance
在 sql server 2012 中,我曾经通过获取 SP_HELP_JOB 的输出来查看作业
-- https://www.sqlservercentral.com/Forums/Topic259078-8-1.aspx
-- getting data from sp_help_job into a temp table
-- marcelo miorelli
-- 01-april-2013
IF OBJECT_ID('TEMPDB..#JOBiNFO') IS NOT NULL
DROP TABLE #JobInfo
IF OBJECT_ID('TEMPDB..#ScheduleInfo') IS NOT NULL
DROP TABLE #ScheduleInfo
SELECT * INTO #JobInfo
FROM OPENROWSET('sqloledb', 'server=(local);trusted_connection=yes'
, 'set fmtonly off exec msdb.dbo.sp_help_job -- @execution_status=4')
SELECT * INTO #ScheduleInfo
FROM OPENROWSET('sqloledb', 'server=(local);trusted_connection=yes'
, 'set fmtonly off exec msdb.dbo.sp_help_schedule')
Run Code Online (Sandbox Code Playgroud)
现在在 sql server 2016 上这不起作用。
我收到此错误消息:
消息 11520,级别 16,状态 1,过程 sp_describe_first_result_set,第 1 …
dynamic-sql ×10
sql-server ×7
postgresql ×3
permissions ×2
plpgsql ×2
t-sql ×2
ddl ×1
exec ×1
jobs ×1
openrowset ×1
parameter ×1
performance ×1