There are several SQL servers having stored procedures, for example Microsoft SQL Server or PostgreSQL. There are also several client side objects implementing stored procedures calls (TADOStoredProc
in Delphi, SqlCommand
in .NET Framework etc.).
The question I always wanted to ask is:
are stored procedures executed always in special efficient way with binary representation of their parameters or are the super-advanced objects which represent stored procedures' parameters always converted to a plain text string and stored procedure is always executed by sending this plain text string to SQL server? (Let's take one technology for example - let it be SQL Server and ADO.NET).
I noticed that for ADO.NET procedure's parameter names do not have any meaning - only their creation order is important which makes me think about an idea with plain text string.
Update for @Alex K.
I've tested following code in .NET:
CREATE PROCEDURE paramtest
@par1 nvarchar(50),
@par2 nvarchar(50),
@par3 nvarchar(50)
AS
SELECT Res = '@par1 = ' + @par1 + '; @par2 = ' + @par2 + '; @par3 = ' + @par3
RETURN 555
using System;
using System.Data.SqlClient;
using System.Data;
namespace SqlParamTest
{
class Program
{
private static void addParam(SqlCommand cmd, string parameterName, ParameterDirection direction, SqlDbType dbType, int size, object value)
{
SqlParameter par = new SqlParameter(parameterName, dbType, size);
par.Direction = direction;
par.Value = value;
cmd.Parameters.Add(par);
}
static void Main(string[] args)
{
using (SqlConnection conn = new SqlConnection(@"Data Source=localhost\sqlexpress;Initial Catalog=test;Integrated Security=True"))
{
SqlCommand cmd = conn.CreateCommand();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "paramtest";
addParam(cmd, "@par3", ParameterDirection.Input, SqlDbType.NVarChar, 50, "third");
addParam(cmd, "@par2", ParameterDirection.Input, SqlDbType.NVarChar, 50, "second");
addParam(cmd, "@par1", ParameterDirection.Input, SqlDbType.NVarChar, 50, "first");
addParam(cmd, "@Return", ParameterDirection.ReturnValue, SqlDbType.Int, 0, null);
conn.Open();
SqlDataReader rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
if (rdr.Read()) Console.WriteLine((string)rdr["Res"]);
rdr.Close();
Console.WriteLine("Return value: {0}", cmd.Parameters["@Return"].Value);
}
Console.ReadKey();
}
}
}
and yes, it maintains parameters in a right way, but I think, it is .NET who adds additional checks to parameters, because following code in 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;
returns:
@par1 = one; @par2 = two; @par3 = three
and doesn't complain about missing parameters.
pdReturnValue works only if this parameter is created before any other parameters.