2012-03-10 26 views
14

He una base de datos estructurada de la siguiente manera:INSERT INTO si no existe el servidor SQL

usuarios

userid (Primary Key) 
username 

grupo

groupid (PK) 
groupName 

user_groups

userid (Foreign Key) 
groupid (Foreign Key) 

La primera vez que un usuario inicia sesión me gustaría que su información se agregue a la tabla de usuarios. Entonces, esencialmente la lógica que me gustaría tener si

if (//users table does not contain username) 
{ 
INSERT INTO users VALUES (username); 
} 

¿Cómo puedo hacer esto de forma inteligente utilizando SQL Server/C#?

Respuesta

19

O usando la nueva sintaxis de MERGE:

merge into users u 
using ( 
    select 'username' as uname 
) t on t.uname = u.username 
when not matched then 
    insert (username) values (t.uname); 
+0

Bueno (aunque probablemente sea innecesario cuando se contempla una sola acción) –

+1

@Damien_The_Unbeliever - Vale la pena considerarlo cuando tiene [concurrencia alta] (http://dba.stackexchange.com/a/13384/2103). Probablemente no sea el caso aquí, pero +1 de mí. –

+0

@MikaelEriksson: indica que todavía necesita '' serializable' para evitar algunos problemas. ¿Existe alguna clara diferencia entre este y otros enfoques? –

10

Básicamente, usted puede hacerlo de esta manera:

if NOT exists (select * from user where username = @username) 
    insert into users values (username) 

Pero en serio, ¿cómo vas a saber si el usuario visita su sitio web por primera vez? Tiene que insertar registros en el usuario de la tabla, cuando alguien se registra en su sitio web, no inicia sesión.

+0

@Damien_The_Unbeliever, gracias! – user194076

+4

En una nota totalmente lateral: has ganado más de 1K rep hasta ahora, ¿no es hora de elegir un nombre decente? –

+0

sabré si están iniciando sesión por primera vez ya que su nombre estará en la base de datos. No hay registro en mi sitio web; Uso autenticación externa desde otro sitio :). ¡Gracias por la respuesta! –

3
IF NOT EXISTS (select * from users where username = 'username') 
BEGIN 
    INSERT INTO ... 
END 
0

Aquí está un ejemplo (probablemente simplificado) que se ocupa de su problema. Tenga en cuenta que siempre es mejor usar parámetros para evitar ataques de inyección, especialmente al verificar usuarios.

CREATE PROCEDURE AddUser 
    @username varchar(20) 
AS 
    IF NOT EXISTS(SELECT username FROM users WHERE [email protected]) 
    INSERT INTO users(username) VALUES (@username) 
1

El código siguiente es un método que devuelve 0 si el usuario ya existe y devuelve el nuevo usuario ID que se agregó:

private int TryToAddUser(string UserName) 
     { 
      int res = 0; 
      try 
      { 
       string sQuery = " IF NOT EXISTS (select * from users where username = @username) \n\r" + 
       " BEGIN \n\r" + 
       "  INSERT INTO users values (@username) \n\r" + 
       " SELECT SCOPE_IDENTITY() \n\r " + 
       " END \n\r " + 
       " ELSE SELECT 0"; 
       using (System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand()) 
       { 
        cmd.CommandText = sQuery; 
        cmd.Parameters.AddWithValue("@username",UserName); 
        cmd.Connection = new System.Data.SqlClient.SqlConnection("SomeSqlConnString"); 
        cmd.Connection.Open(); 
        res = (int)cmd.ExecuteScalar(); 
        cmd.Connection.Close(); 
       } 
      } 
      catch (Exception ex) 
      { 
       MessageBox.Show(ex.Message); 
      } 
      return res; 
     } 
3

quisiera en primer lugar crear un procedimiento almacenado en la base de datos de hacer el cheque e inserte si es necesario:

CREATE PROCEDURE AddNewUserProc 
(
@username  VarChar(50) -- replace with your datatype/size 
) 

AS 

    IF NOT EXISTS (SELECT * FROM users WHERE username = @username) 
    BEGIN 
     INSERT INTO users 
     VALUES (@username) 
    END 

a continuación, un método en la aplicación que va a llamar a este procedimiento

public void AddNewUserMethod(string userName) 
{ 
    SqlConnection connection = new SqlConnection("connection string"); 
    SqlCommand command = new SqlCommand("AddNewUserProc", connection); 

    command.CommandType = CommandType.StoredProcedure; 
    command.Parameters.Add("username", SqlDbType.VarChar, 50).Value = userName; 

    try 
    { 
     connection.Open(); 
     command.ExecuteNonQuery(); 
    } 
    finally 
    { 
     if (connection.State == ConnectionState.Open) { connection.Close(); } 
    } 
} 
1

@gbn respuesta necesita SQL Server 2008 o posterior. Intenté una forma de no fusión para hacerlo. Feo, tal vez, pero funciona.

declare @user varchar(50) 
set @user = 'username' 
insert into users (username) 
select @user 
where not exists (
select username 
from users 
where username = @user 
); 

Si desea probar alguna de las respuestas, aquí es el SQL para la tabla -

CREATE TABLE [dbo].[users](
    [userid] [int] NULL, 
    [username] [varchar](50) NULL 
) 

INSERT [dbo].[users] ([userid], [username]) VALUES (1, N'John') 
INSERT [dbo].[users] ([userid], [username]) VALUES (2, N'David') 
INSERT [dbo].[users] ([userid], [username]) VALUES (3, N'Stacy') 
INSERT [dbo].[users] ([userid], [username]) VALUES (4, N'Arnold') 
INSERT [dbo].[users] ([userid], [username]) VALUES (5, N'Karen') 
Cuestiones relacionadas