Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 我可以使用存储过程通过传递列名来更新不同的列吗?_Sql Server_Vba_Stored Procedures - Fatal编程技术网

Sql server 我可以使用存储过程通过传递列名来更新不同的列吗?

Sql server 我可以使用存储过程通过传递列名来更新不同的列吗?,sql-server,vba,stored-procedures,Sql Server,Vba,Stored Procedures,我第一次使用存储过程(这是在Outlook 2007 VBA中),我想知道是否需要为记录集中的每一列使用不同的过程,或者是否可以将列名作为变量传递?我写了以下内容来尝试这样做,但我得到了错误 运行时错误“3709”: 连接无法用于执行此操作。要么是 在此上下文中已关闭或无效 这是我的密码 调用ConnectToDatabase KA_Com.CommandText=“ReadLeagues” KA_Com.CommandType=adCmdStoredProc 设置KA_参数=KA_Com.Cr

我第一次使用存储过程(这是在Outlook 2007 VBA中),我想知道是否需要为记录集中的每一列使用不同的过程,或者是否可以将列名作为变量传递?我写了以下内容来尝试这样做,但我得到了错误

运行时错误“3709”:

连接无法用于执行此操作。要么是 在此上下文中已关闭或无效

这是我的密码

调用ConnectToDatabase
KA_Com.CommandText=“ReadLeagues”
KA_Com.CommandType=adCmdStoredProc
设置KA_参数=KA_Com.CreateParameter(名称:=“pLeagueName”,类型:=adChar,大小:=Len(KAleague))
KA_Com.Parameters.Append KA_参数
KA_Com.Parameters(“pLeagueName”).Value=UCase(KAleague)
设置KA_RS_Leagues=KA_Com.Execute
如果卡乌尔苏联盟![会话]>0然后
MsgBox“电子邮件已接收到设备列表附件,但会话不是0或-1。电子邮件已移动到“未知”文件夹”
电子邮件。移动子文件夹2
MySkip=True
出口接头
如果结束
Atmt.SaveAsFile KApath&KAleague&“/Current Season/”&Atmt.FileName
Atmt.SaveAsFile KApath&KAleague&“/Current Season/Fixtures.txt”
子文件夹1.项目(EMailNo).删除
Set KA_Com=New ADODB.Command
KA_Com.CommandText=“更新邮件”
KA_Com.CommandType=adCmdStoredProc
设置KA_参数=KA_Com.CreateParameter(名称:=“pLeagueId”,类型:=adInteger)
KA_Com.Parameters.Append KA_参数
KA_Com.Parameters(“pLeagueId”).Value=KA_RS_Leagues![ID]
设置KA_参数=KA_Com.CreateParameter(名称:=“pColumnName”,类型:=adChar,大小:=11)
KA_Com.Parameters.Append KA_参数
KA_Com.Parameters(“pColumnName”).Value=“FixtureList”
设置KA_参数=KA_Com.CreateParameter(名称:=“pColumnValue”,类型:=adInteger,大小:=1)
KA_Com.Parameters.Append KA_参数
KA_Com.Parameters(“pColumnValue”)。值=1

设置KA_RS_Leagues=KA_Com.Execute您需要使用sp_execitesql在存储过程中运行

CREATE PROCEDURE [dbo].[UpdateEmails]
@pLeagueId int,
@pColumnName nChar,
@pColumnValue int

AS
DECLARE @Sql as nvarchar(max)
SET @Sql = N'UPDATE [dbo].[Emails] SET ' + QUOTENAME(@pColumnName) + ' = CAST(@pColumnValue AS varchar(20) WHERE [League] = CAST(@pLeagueId AS varchar(20);'

EXECUTE sp_executesql @Sql, @pColumnValue, @pLeagueId
GO

动态SQL将是最简单的解决方案。做对了:

创建过程[dbo].[UpdateEmails]
@leagueId int不为空
,@columnName nvarchar(50)不为空--注意封顶长度;根据需要进行调整
,@columnValue int不为空
作为
开始
--忘记这一点会使ADODB客户机陷入混乱,尤其是SELECT查询:
不计数;
--动态SQL的参数:
声明@sqlParams nvarchar(max)=N'
@leagueId int不为空
,@columnValue int不为空
';
--构建动态SQL,注意QUOTENAME和参数用法:
声明@sql nvarchar(最大)=N'
更新[dbo]。[电子邮件]
设置“+QUOTENAME(@columnName)+”=@columnValue
其中[LeagueId]=@LeagueId;
';
--运行它:
执行sp_executesql@sql、@sqlParams、@leagueId、@columnValue;
结束

也就是说,需要动态列名闻起来像是
[dbo].[Emails]
没有正确规范化:理想的解决方案可能是回到绘图板上。

我不接受上述任何答案,因为我没有走这条路,让事情变得过于复杂,我刚刚为每个变量创建了一个不同的存储过程&VBA routind


不过,感谢您的帮助性回复,希望他们将来能帮助其他人……

值得一提的是,在哪一行出现了错误。用F8单步执行代码,并注意突出显示错误的位置。说到这里,我指的是你的问题。不,你不能参数化对象或列名。这需要动态sql。为什么您现在知道要更新哪个列?这通常是设计未正确规范化的标志。您知道update语句中的列列表吗?这可能在没有动态sql的情况下完成。@SeanRange 100%同意:需要动态列名闻起来像是非规范化数据。特别是给定的
@pColumnValue
是一个
int
。我很想看看实际表格的
创建表格
脚本。此外,您还需要在模块顶部指定
选项Explicit
,并声明您正在使用的所有变量。这将“起作用”,直到bobby tables来访问。这对sql注入是完全开放的。至少你应该把列名用引号括起来以帮助他。我同意这一点,但我不是来解决他的sec问题的。在你建议他使用不安全代码之前,这里没有一个问题需要解决。至少您应该提到您的代码是易受攻击的。似乎OP是相当新的,可能会把你的代码作为一种很好的方式来做。我之所以用这种方式来编写代码,唯一的原因是因为我的原始代码被指出对SQL注入非常开放!!!我相信这将是错误的,因为pColmnValue是一个int,您不能将它添加到stringThis中,这对sql注入也是非常开放的。
CREATE PROCEDURE [dbo].[UpdateEmails]
@pLeagueId int,
@pColumnName nChar,
@pColumnValue int

AS
DECLARE @Sql as nvarchar(max)
SET @Sql = N'UPDATE [dbo].[Emails] SET ' + QUOTENAME(@pColumnName) + ' = CAST(@pColumnValue AS varchar(20) WHERE [League] = CAST(@pLeagueId AS varchar(20);'

EXECUTE sp_executesql @Sql, @pColumnValue, @pLeagueId
GO