【问题标题】:stored procedure return value in management studio but not in c# codeManagement Studio 中的存储过程返回值,但 C# 代码中没有
【发布时间】:2024-05-04 16:15:02
【问题描述】:

我有一个使用链接服务器 (ADSI) 连接到活动目录的存储过程。它接受一个字符串/varchar guid,然后从活动目录返回用户的 thumbnailPhoto 属性。我正在尝试从 C# 代码调用此过程,但它一直返回 null。我试图确保传递的 guid 是正确的,所以从调试中,我抓住了传递给参数的 guid,然后尝试使用它在管理工作室中运行存储过程。结果很好,但是当我从我的应用程序中执行此操作时,我得到了空值。代码如下:

SPROC:

ALTER PROC [dbo].[sp_GetPhotoFromADSI] 
                @GUID varchar(100)
AS 
                SET NOCOUNT ON 
                SET XACT_ABORT ON  

                BEGIN TRAN

                DECLARE @sql NVARCHAR(600)

                SET @sql=N'SELECT thumbnailPhoto FROM OPENQUERY(ADSI,
                                ''SELECT thumbnailPhoto 
                                  FROM ''''LDAP://<GUID=' + @GUID + '>'''' 
                                  WHERE objectCategory = ''''Person'''' AND objectClass = ''''user'''''')'

                EXEC SP_EXECUTESQL @sql

                COMMIT

C#:

private byte[] GetUserPhotoByGuid(Guid userNativeGuid)
{
    //dont judge me for not abstracting this
    var connString = "connectionStringCrap;";
    byte[] photo = null;

    using (var conn = new SqlConnection(connString))
    {
        try
        {
            string guidString = userNativeGuid.ToString();

            //var realGuid = Guid.Parse(userNativeGuid);
            using (var comm = new SqlCommand("sp_GetPhotoFromADSI", conn))
            {
                comm.CommandType = CommandType.StoredProcedure;
                comm.Parameters.AddWithValue("@GUID", guidString);
                var returnParameter = comm.Parameters.Add("@Output", SqlDbType.Binary);
                returnParameter.Direction = ParameterDirection.ReturnValue;
                conn.Open();
                comm.ExecuteScalar();

                photo = returnParameter.Value as byte[];
                return photo;                       
            }
        }
        catch (Exception)
        {
            throw;
        }
        finally
        {
            conn.Close();
        }

    }
    return null;
}

【问题讨论】:

  • 这个存储过程好像没有任何输出参数。
  • 只是一个想法:直接从 C# 代码访问 AD 而不是绕道 SQL Server 访问 AD 会不会容易得多?参见例如this SO question on the same topic 一些指针
  • 其实是也不是。我的原始代码是通过 DirectoryServices 来实现的,这要容易得多,但我们发现使用 SQL 要快得多。
  • GUID 是什么样的?我肯定会建议直接通过 ADSI 执行此操作。 SQL 无法让这更快

标签: c# sql-server stored-procedures active-directory


【解决方案1】:

该值将由ExecuteScalar()返回。

Byte[] photo = (Byte[])comm.ExecuteScalar();

【讨论】:

  • 照片最终成为长度至少为 31100 的字节数组。我还有哪些其他选择?
【解决方案2】:

您可能想要 ExecuteScalar 返回的结果。但请记住,它最多只能返回 2033 个字符。

【讨论】:

  • 照片最终成为长度至少为 31100 的字节数组。我还有哪些其他选择?
  • 在实际尝试此方法之前,我使用了 sqldatareader。问题是它返回 null 一样。当我在管理工作室中运行查询时,数据恢复得很好。当我在调试中单步执行它时,我正在查看枚举,它显示它有一个结果/记录,但该记录是空的。这对我来说没有任何意义:/