C# 检查sql中是否存在来自c的登录名

C# 检查sql中是否存在来自c的登录名,c#,sql,C#,Sql,在一个类中,我正在创建登录到sql的日志,这很好。我想在第一次检查中添加一点错误检查,看看登录名是否已经存在于SQL中。如果有,则不要尝试添加登录,而是映射到表等 在sql中,我使用以下命令检查登录: select name from sys.server_principals where name = 'viewer2' 我厌倦了在我的课堂上使用这个,如下所示 protected static bool CheckForExistingUser(DbContext context, stri

在一个类中,我正在创建登录到sql的日志,这很好。我想在第一次检查中添加一点错误检查,看看登录名是否已经存在于SQL中。如果有,则不要尝试添加登录,而是映射到表等

在sql中,我使用以下命令检查登录:

select name from sys.server_principals where name = 'viewer2'
我厌倦了在我的课堂上使用这个,如下所示

protected static bool CheckForExistingUser(DbContext context, string userName)
        {
            string checkForUser =
                @" SET NOCOUNT ON
                    DECLARE @userName AS nvarchar(max) = {0}
                    EXEC('
                    SELECT name FROM sys.server_principals where name = ['+ @userName +']
                    ')";
            return Convert.ToBoolean(context.Database.ExecuteSqlCommand(checkForUser, userName));
        }
然而,当我调用这个方法时,我得到一个异常,即作为传入的用户名的列是无效的

$exception  {"Invalid column name 'viewer2'."}  System.Exception {System.Data.SqlClient.SqlException}
关于是什么导致了这种情况,有没有更好的方法来检查sql db from代码中是否存在登录

干杯

围绕你的价值观,你应该使用'而不是[]。否则,SQL server将其视为列名

string checkForUser =
    @" SET NOCOUNT ON
        DECLARE @userName AS nvarchar(max) = {0}
        EXEC('
        SELECT name FROM sys.server_principals where name = ''' + @userName +'''
        ')";
您应该在您的值周围使用'而不是[]。否则,SQL server将其视为列名

string checkForUser =
    @" SET NOCOUNT ON
        DECLARE @userName AS nvarchar(max) = {0}
        EXEC('
        SELECT name FROM sys.server_principals where name = ''' + @userName +'''
        ')";
试一试:

protected static bool CheckForExistingUser(DbContext context, string userName)
        {
            return Convert.ToBoolean(context.Database.ExecuteSqlCommand("SELECT name FROM sys.server_principals where name = {0}", userName));
        }
计数将返回0或1,这取决于用户名是否满足布尔转换。。。还删除了代码中的所有修剪。如果它不起作用,请告诉我。

试一试:

protected static bool CheckForExistingUser(DbContext context, string userName)
        {
            return Convert.ToBoolean(context.Database.ExecuteSqlCommand("SELECT name FROM sys.server_principals where name = {0}", userName));
        }

计数将返回0或1,这取决于用户名是否满足布尔转换。。。还删除了代码中的所有修剪。如果不起作用,请告诉我。

正如@MarcinJuraszek所回答的,字符串参数周围不能有“[”。它们必须有单引号,或者如果作为参数发送,则会自动被引用

由于看起来您使用的是实体框架,我认为您可以通过执行更简单的查询使其更具可读性。在.NET Framework 4.0及更高版本中,您可以执行以下操作:

string checkForUser = "SELECT count(1) FROM sys.server_principals where name = {0}";
return context.ExecuteStoreQuery<int>(checkForUser, userName).First() > 0;

正如@MarcinJuraszek所回答的,字符串参数周围不能有“[”。它们必须有单引号,或者在作为参数发送时自动被引用

由于看起来您使用的是实体框架,我认为您可以通过执行更简单的查询使其更具可读性。在.NET Framework 4.0及更高版本中,您可以执行以下操作:

string checkForUser = "SELECT count(1) FROM sys.server_principals where name = {0}";
return context.ExecuteStoreQuery<int>(checkForUser, userName).First() > 0;


我不确定我是否同意这样将我的用户帐户id直接绑定到我的数据库。这像是一个内部开发工具吗?我可以问一下,为什么要这样做存储过程,而不是将其添加到服务器上..?手动运行此操作时会发生什么..?打开SQL Server profiler,查看发送到DB.Thi的内容这样,您将来就可以知道如何调试这些东西了。您可以复制/粘贴sent语句到SQL Management Studio并播放,直到您看到问题所在。我不确定是否可以将我的用户帐户id直接绑定到我的数据库,就像这样。这像是一个内部开发工具吗?请问您为什么要这样做tored proc的这种方式与将其添加到服务器上的方式相反..?手动运行时会发生什么情况..?打开SQL Server profiler并查看发送到DB的内容。通过这种方式,您将知道将来如何调试这些内容。您可以将发送的语句复制/粘贴到SQL Management Studio并播放,直到您看到问题所在。您在哪里找到问题你在这里看到SQL注入了吗?但是你可以在@userName之前和之后删除+我想。@PetarRepac当userName被设置为例如“或1=1或=”时会发生什么?什么都没有。你把这个值作为参数传递,而不是字符串串接。对……很抱歉,假警报:tsql中的IIRC转义单引号是通过将它们加倍来实现的。其中name='1+@userName+'应该可以更好地工作。您在这里看到SQL注入了吗?但是您可以在@userName之前和之后删除+。@PetarRepac当userName设置为例如“或1=1或=”时会发生什么情况?什么都没有。您将此值作为参数传递,而不是字符串串联。对…很抱歉出现错误警报:IIRC在t中转义单引号sql是通过将它们加倍来生成的。其中name='+@userName+'应该可以更好地单独工作,但我编写它的方式是,我将尝试使用该用户进行身份验证,以检查它们是否存在,然后在失败时做些什么。哎哟,sql注入!将该查询参数化。我认为这不起作用,因为Database.ExecuteSqlCommand是返回的我认为,在这种情况下,查询执行结果影响的行不是计数值。@PHeiberg您在这两个计数上都是对的,没有注意到executesqlcommand的返回类型…在这里似乎使用了错误的对象,但我不太了解实体。另外,参数化了。我尝试尽可能接近原始代码gh.但就我个人而言,我编写它的方式是,我会尝试使用该用户进行身份验证,以检查它们是否存在,然后在失败时执行某些操作。哎哟,SQL注入!对该查询进行参数化。我认为这不会起作用,因为Database.ExecuteSqlCommand将返回查询执行结果受影响的行。我认为,在这种情况下,不是count value.@PHeiberg您在这两个方面都是对的,没有注意到executesqlcommand的返回类型…在这里似乎使用了错误的对象,但我不太了解实体。另外,第 公制化。不过,我会尽量接近原始代码。