Sql 存储过程是从文本字符串执行的吗?

Sql 存储过程是从文本字符串执行的吗?,sql,stored-procedures,request,binary-data,plaintext,Sql,Stored Procedures,Request,Binary Data,Plaintext,有几个SQL Server具有存储过程,例如Microsoft SQL Server或PostgreSQL。还有几个客户端对象实现存储过程调用(tadostredproc在Delphi中,SqlCommand在.netframework中等等) 我一直想问的问题是: 存储过程的参数是否始终以二进制表示的特殊高效方式执行,或者表示存储过程参数的超高级对象是否始终转换为纯文本字符串,并且存储过程始终通过将此纯文本字符串发送到SQL server来执行?(让我们以一种技术为例——SQL Server和

有几个SQL Server具有存储过程,例如Microsoft SQL Server或PostgreSQL。还有几个客户端对象实现存储过程调用(
tadostredproc
在Delphi中,
SqlCommand
在.netframework中等等)

我一直想问的问题是:

存储过程的参数是否始终以二进制表示的特殊高效方式执行,或者表示存储过程参数的超高级对象是否始终转换为纯文本字符串,并且存储过程始终通过将此纯文本字符串发送到SQL server来执行?(让我们以一种技术为例——SQL Server和ADO.NET)

我注意到,对于ADO.NET过程,参数名没有任何意义——只有它们的创建顺序很重要,这让我想到了纯文本字符串

更新@Alex K.

我在.NET中测试了以下代码:

CREATE PROCEDURE paramtest
@par1 nvarchar(50),
@par2 nvarchar(50),
@par3 nvarchar(50)
AS
  SELECT Res = '@par1 = ' + @par1 + '; @par2 = ' + @par2 + '; @par3 = ' + @par3
  RETURN 555

是的,它以正确的方式维护参数,但我认为,是.NET为参数添加了额外的检查,因为Delphi中的以下代码:

procedure TMyClass.Test(Conn: TADOConnection);
var SP:TADOStoredProc;
begin
  SP := TADOStoredProc.Create(nil);
  try
    SP.Connection := Conn;
    SP.ProcedureName := 'paramtest';
    SP.Parameters.CreateParameter('@whatthehell', ftString, pdInput, 50, 'one');
    SP.Parameters.CreateParameter('@AnotherCrap', ftString, pdInput, 50, 'two');
    SP.Parameters.CreateParameter('?', ftString, pdInput, 50, 'three');
    SP.ExecProc;
  finally
    SP.Free;
  end;
end;
返回:

@par1 = one; @par2 = two; @par3 = three
并且不会抱怨缺少参数


pdReturnValue仅当此参数在任何其他参数之前创建时才起作用。

不确定要查找的答案是什么,存储过程命令文本和参数将传递给驱动程序/提供程序,或通过ADO.NET以本机方式传递给驱动程序/提供程序,ADO.NET将其格式化为TDS(表格数据流)RPC(远程过程调用)消息,然后将其传递给正在使用网络协议的服务器;管道、tcp/ip等。数据以二进制流发送

如果您感兴趣,请参阅Microsoft提供的TDS规范

SQLCommand
存储过程调用确实需要一个参数名,它的OleDB/ODBC只关心顺序,并使用
作为参数占位符,而不是
@name

关于订单

在您的示例中,顺序不相关,因为您为服务器提供了参数的正确名称,因此发送到服务器的是:

exec paramtest @par3=N'third',@par2=N'second',@par1=N'first'
这些信息足以让服务器确定正确的参数/顺序

如果你改成

addParam(cmd, "@xxpar3",
addParam(cmd, "@xxpar2", 
addParam(cmd, "@xxpar1",
服务器将检测到它没有名为
xxxpar*
的参数,并出现“missing@par1”错误

如果您修改了
addParam
,因此它没有设置参数名称。net将创建默认值:

exec paramtest @Parameter1=N'third',@Parameter2=N'second',@Parameter3=N'first'
这将导致上述错误

如果您修改了
addParam
,因此它没有设置参数名称,然后覆盖自动名称

cmd.Parameters.Add(par);
par.ParameterName = "";
这就是要执行的:

 exec paramtest N'third',N'second',N'first'
导致

 @par1 = third; @par2 = second; @par3 = first
我不知道德尔福做什么。。。SQL Server的完整版本附带了一个名为SQL Profiler的工具,该工具显示发送到服务器实例的文本数据,以便您可以准确地看到发生了什么。

不确定要查找的答案是什么,存储过程命令文本和参数会传递给驱动程序/提供程序,或通过ADO.NET以本机方式传递给驱动程序/提供程序,ADO.NET将其格式化为TDS(表格数据流)RPC(远程过程调用)消息,然后通过该消息传递给正在使用网络协议的服务器;管道、tcp/ip等。数据以二进制流发送

如果您感兴趣,请参阅Microsoft提供的TDS规范

SQLCommand
存储过程调用确实需要一个参数名,它的OleDB/ODBC只关心顺序,并使用
作为参数占位符,而不是
@name

关于订单

在您的示例中,顺序不相关,因为您为服务器提供了参数的正确名称,因此发送到服务器的是:

exec paramtest @par3=N'third',@par2=N'second',@par1=N'first'
这些信息足以让服务器确定正确的参数/顺序

如果你改成

addParam(cmd, "@xxpar3",
addParam(cmd, "@xxpar2", 
addParam(cmd, "@xxpar1",
服务器将检测到它没有名为
xxxpar*
的参数,并出现“missing@par1”错误

如果您修改了
addParam
,因此它没有设置参数名称。net将创建默认值:

exec paramtest @Parameter1=N'third',@Parameter2=N'second',@Parameter3=N'first'
这将导致上述错误

如果您修改了
addParam
,因此它没有设置参数名称,然后覆盖自动名称

cmd.Parameters.Add(par);
par.ParameterName = "";
这就是要执行的:

 exec paramtest N'third',N'second',N'first'
导致

 @par1 = third; @par2 = second; @par3 = first
我不知道德尔福做什么。。。SQL Server的完整版本附带了一个名为SQL Profiler的工具,该工具显示发送到服务器实例的文本数据,以便您可以准确地看到发生了什么。