Avatar billede haolan Nybegynder
19. februar 2008 - 21:25 Der er 18 kommentarer og
1 løsning

Last inserted ID i MSSQL

Hej

Jeg har lavet en brugeroprettelse der opretter to rækker i to forskellige tabeller i min db.

En bruger kan oprette en gruppe inkl sig selv samtidigt.

Jeg har lavet det så den først opretter gruppen med en identifier som hedder groupid og derefter selve brugeren der bliver knyttet til gruppen med det groupid. (altså brugeren har en kolonne der hedder groupid)

Hvordan kalder jeg det senest indsatte id når jeg skal oprette brugeren?

Ligesom man i PHP og mysql bare kan skrive mysql_insert_id();
Avatar billede kalp Novice
19. februar 2008 - 21:27 #1
Bruger du tal eller guids?
Hvis du bruger guids kan du lave dem fra koden og dermed kender du dem på forhånd.
Avatar billede haolan Nybegynder
19. februar 2008 - 21:30 #2
Har bare i kolonnen sat identity specifikation til true, så den selv autonummererer.
Avatar billede arne_v Ekspert
19. februar 2008 - 21:32 #3
Afhaenger af databasen.

MySQL: LAST_INSERT_ID()
SQLServer: @@IDENTITY eller SCOPE_IDENTITY()
Sybase: @@IDENTITY
Access: @@IDENTITY
Oracle : bruger sequences
PostgreSQL : bruger sequences
Avatar billede haolan Nybegynder
19. februar 2008 - 21:36 #4
det er MSSQL 2005 jeg bruger..

Jeg har lavet den nedenstående SQL, men den skriver som fejlmeddelse at groupid ikke kan være null

INSERT INTO t_users ([username], [password], [email], [stammenavn], [ircnick], [groupid]) VALUES (@username, @password, @email, @heroesid, @stammenavn, @ircnick, scope_identity())

Har også prøvet med @@IDENTITY, men det giver samme fejl.
Avatar billede kalp Novice
19. februar 2008 - 21:38 #5
okay så prøv med

SELECT SCOPE_IDENTITY() AS [SCOPE_IDENTITY]

eller

SELECT @@IDENTITY AS [@@IDENTITY]
Avatar billede arne_v Ekspert
19. februar 2008 - 21:45 #6
Jeg kan taelle 6 feltnavne og 7 vaerdier ....
Avatar billede haolan Nybegynder
19. februar 2008 - 21:47 #7
oh sorry.. Fordi heroesid lige er fjernet :)har ikke noget at gøre med min fejl :)
Avatar billede haolan Nybegynder
19. februar 2008 - 21:48 #8
Har også prøvet din selection i et tidligere forsøg der skrev den noget i stil med: Fejl ved ændring
Avatar billede haolan Nybegynder
19. februar 2008 - 21:54 #9
ved ikke om det evt er mit SQL kald den har været gal med.
Det så sådan ud:

SELECT @@IDENTITY AS [NewID] FROM t_groups
Avatar billede haolan Nybegynder
19. februar 2008 - 21:54 #10
nej sorry

SELECT @@IDENTITY AS 'NewID' FROM t_clans

sådan
Avatar billede haolan Nybegynder
19. februar 2008 - 21:56 #11
Fejlmeddelsen ser sådan ud: {"Den angivne ændring er ugyldig."}
Avatar billede mikalj Nybegynder
20. februar 2008 - 11:21 #12
Nu hører dette nok mere til under mssql sektionen, da det ikke direkte har noget med asp.net

men for at scope_identity() skal virke (og scope_identity() er det korrekte at bruge) skal det være en del af samme batch.

INSERT INTO gruppe (gruppenavn, felt1, felt2, etc)
VALUES (@gruppenavn, @felt1, @felt2, @etc);
DECLARE @gId AS INT;
SET @gId = (SELECT SCOPE_IDENTITY());

INSERT INTO bruger (brugernavn, adgangskode, gruppeid)
VALUES (@brugernavn, @adgangskode, @gId);
Avatar billede arne_v Ekspert
20. februar 2008 - 14:11 #13
Forkert. Det skal bare være samme connection.
Avatar billede mikalj Nybegynder
20. februar 2008 - 17:05 #14
Min terminologi er måske forkert.
Min pointe var at SCOPE_IDENTITY() returnerer den sidste id der er indsat i samme forespørgsel, mens @@IDENTITY returnerer den sidste id der indsat i samme session (altså forbindelse)
Det er i hver fald hvad microsoft påstår
http://msdn2.microsoft.com/en-us/library/ms190315.aspx

under alle omstændigheder vil løsningen i mit første svar virke.
Avatar billede arne_v Ekspert
20. februar 2008 - 17:11 #15
Nej.

Baade SCOPE_IDENTITY() og @@IDENTITY er per connection (session).

Forskellen er at @@IDENTITY er sidste uanset hvad mens SCOPE_IDENTITY() er
sidste i current scope (paa almindeligt dansk: den bliver ikke overskrevet
hvis ens insert resulterer i at en trigger koeres som laver en ny indsaet
der genererer en ny identity).
Avatar billede arne_v Ekspert
20. februar 2008 - 17:12 #16
Der er ioevrigt ikke nogen grund til at selecte vaerdien til en variabel for
at lave 2 x insert:

INSERT INTO ... (...) VALUES (...);
INSERT INTO ... (...) VALUES (...,SCOPE_IDENTITY(),...);

virker fint.
Avatar billede haolan Nybegynder
22. februar 2008 - 13:49 #17
Nu har jeg sat dem ind i samme connection, men scope identity bliver stadig null.

Min kode er her:

        SqlCommand cmd = new SqlCommand();
        SqlConnection con;

        string connectionstring = ConfigurationManager.ConnectionStrings["klansidenConnectionString"].ConnectionString;
        con = new SqlConnection(connectionstring);

        string sqlStr = "INSERT INTO t_clans ([name], [irc_server], [irc_channel], [iap_spy], [iap_visibility]) VALUES (@name, @irc_server, @irc_channel, @iap_spy, @iap_visibility)";
        string addUser = "INSERT INTO t_users ([username], [password], [email], [heroesid], [stammenavn], [ircnick], [clanid]) VALUES (@username, @password, @email, @heroesid, @stammenavn, @ircnick, SCOPE_IDENTITY())";

        SqlParameter p = new SqlParameter("@name", clan.Name);
        p.DbType = DbType.String;
        cmd.Parameters.Add(p);

        p = new SqlParameter("@irc_server", clan.Ircserver);
        p.DbType = DbType.String;
        cmd.Parameters.Add(p);

        p = new SqlParameter("@irc_channel", clan.Ircchannel);
        p.DbType = DbType.String;
        cmd.Parameters.Add(p);

        p = new SqlParameter("@iap_spy", clan.Iap_spy.ToString());
        p.DbType = DbType.String;
        cmd.Parameters.Add(p);

        p = new SqlParameter("@iap_visibility", clan.Iap_visibility.ToString());
        p.DbType = DbType.String;
        cmd.Parameters.Add(p);

        p = new SqlParameter("@username", user.Username);
        p.DbType = DbType.String;
        cmd.Parameters.Add(p);

        p = new SqlParameter("@password", user.Password);
        p.DbType = DbType.String;
        cmd.Parameters.Add(p);

        p = new SqlParameter("@email", user.Email);
        p.DbType = DbType.String;
        cmd.Parameters.Add(p);

        p = new SqlParameter("@heroesid", user.HeroesID);
        p.DbType = DbType.Int32;
        cmd.Parameters.Add(p);

        p = new SqlParameter("@stammenavn", user.Stammenavn);
        p.DbType = DbType.String;
        cmd.Parameters.Add(p);

        p = new SqlParameter("@ircnick", user.IRCNick);
        p.DbType = DbType.String;
        cmd.Parameters.Add(p);

        cmd.Connection = con;
        cmd.CommandText = sqlStr;

        SqlDataReader sr;
        int res = 0;

        try
        {
            con.Open();
            cmd.ExecuteNonQuery();
            cmd.CommandText = addUser;
            cmd.ExecuteNonQuery();
        }
        catch (Exception ex)
        {
            throw ex;
        }
        finally
        {
            con.Close();
        }
Avatar billede haolan Nybegynder
22. februar 2008 - 14:49 #18
Har nu bygget det op med transaktioner, så min kode der opretter ser sådan ud:

    public void AddClan(Clan clan, User user)
    {
        Transaction trans = new Transaction();
        trans.BeginTransaction();

        try
        {
            ClanGateway cg = new ClanGateway();
            cg.Name = clan.Name;
            cg.IRC_server = clan.Ircserver;
            cg.IRC_channel = clan.Ircchannel;
            cg.IAP_spy = clan.Iap_spy;
            cg.IAP_visibility = clan.Iap_visibility;
            cg.Insert(trans);

            UserGateway ug = new UserGateway();
            ug.Username = user.Username;
            ug.Password = user.Password;
            ug.Email = user.Email;
            ug.Heroesid = user.HeroesID;
            ug.Stammenavn = user.Stammenavn;
            ug.IRCNick = user.IRCNick;
            ug.Insert(trans, false);
        }
        catch (Exception e)
        {
            trans.Rollback();
            throw e;
        }

        trans.Commit();

Men scope_identity() bliver stadig null..
Avatar billede haolan Nybegynder
29. februar 2008 - 19:09 #19
Kunne kun få det til at virke med en stored procedure.. Hvilket også ret udemærket i mit tilfælde.

Takker for jeres forsøg på hjælp ellers :)

:-Haolan
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester