Avatar billede musicchart.dk Nybegynder
07. juli 2006 - 13:25 Der er 21 kommentarer og
1 løsning

autonummeringens næste id

Jeg skal til en app. bruge postens id nr, til gentagne indsættelser i database, i forskellige tabeller, men i samme omgang.

Kan man på nogen måde, indsætte en ny (evt. tom) række i den tabel hvor autonummeringen finder sted, hvorefter trække id'et ud?

Man kunne selvfølgelig lave en forspørgsel hvor man søger på de oplysninger man indsatte da man oprettede rækken, og så trække id'et ud på den måde, men det er bare ikke optimalt til det jeg skal bruge.

Jeg regner med at det er umuligt, men nu spørger jeg altså alligevel.
Avatar billede snepnet Nybegynder
07. juli 2006 - 14:13 #1
Du kan få oplysningen f.eks. sådan her:

SqlConnection con = new SqlConnection("someconnectionstring");
SqlCommand command = new SqlCommand("insert into blah (...) values (...);set @id = SCOPE_IDENTITY()", con);
SqlParameter personId = new SqlParameter("@id", SqlDbType.Int);
personId.Direction = ParameterDirection.Output;
command.Parameters.Add(id);
con.Open();
command.ExecuteNonQuery();
int id = (int)id.Value;
con.Close();

Men du kan også lave en select SCOPE_IDENTITY() som afsluttende sql, og få værdien med ExecuteScalar istedet - men jeg vil anbefale dig den ovenfor beskrevne.

Mvh
Avatar billede mikkel_sommer Nybegynder
07. juli 2006 - 14:14 #2
Du kan bruge:

select count (*)
from myTable

Det vil give dig antallet af nuværende rækker.
Avatar billede musicchart.dk Nybegynder
07. juli 2006 - 15:06 #3
snepnet >> det ser jo perfekt ud! Jeg har dog ikke testet det endnu.

Kan jeg få dig til at kommentere lidt af koden, og forklare hvad den gør.
Avatar billede snepnet Nybegynder
07. juli 2006 - 15:38 #4
Jada:

// instantier SqlConnection objekt - med en connectionstring i constructoren
SqlConnection con = new SqlConnection("someconnectionstring");
// instantier SqlCommand objekt med angivelse af en sql kommando
// som sidste statement sættes parameteren @id til SCOPE_IDENTITY() således
// at det netop genererede id angives på parameteren
SqlCommand command = new SqlCommand("insert into blah (...) values (...);set @id = SCOPE_IDENTITY()", con);
// instantierer en SqlParameter med navnet @id - som angivet i sql'en
SqlParameter personId = new SqlParameter("@id", SqlDbType.Int);
// parameteren angives som outputparameter
personId.Direction = ParameterDirection.Output;
// og tilføjes kommandoobjektet
command.Parameters.Add(id);
// databasen åbnes
con.Open();
// kommandoen eksekveres
command.ExecuteNonQuery();
// og værdien af outputparameteren typecastes til en integer som så indeholder id'et
int id = (int)id.Value;
// forbindelsen lukkes
con.Close();

Jeg har ikke udfyldt en specifik insert-kommando.... Tænker mig at du har din egen ;o)

Mvh
Avatar billede musicchart.dk Nybegynder
07. juli 2006 - 16:20 #5
Det er jo helt perfekt :o)
Jeg har bare aldrig hørt om SCOPE_IDENTITY() før.

Smider du et svar, så lægger jeg 100 point oveni, som tak for hjælpen ;o)
Avatar billede snepnet Nybegynder
07. juli 2006 - 16:46 #6
Det var bestemt så lidt :o)
Mvh
Avatar billede websam Nybegynder
07. juli 2006 - 19:25 #7
Udskyld, men var det ikke lidt lettere med Select @@Identity efter indsættelse ?

/Websam
Avatar billede snepnet Nybegynder
07. juli 2006 - 22:56 #8
Som tidligere nævnt også en mulighed ... Men parametre er nu engang nogle lækre størrelser ;o)
Mvh
Avatar billede arne_v Ekspert
08. juli 2006 - 02:02 #9
Der er ligesom 3 dimensioner i det her:

1)  @@IDENTITY versus SCOPE_IDENTITY()

Normalt vil de returnere det samme, men hvis man bruger nogle specielle
INSERT triggers som laver INSERT i andre tabeller kan de returnere
forskelligt - og så er det normalt altid det SCOPE_IDENTITY() returnerer
som man vil have - derfor anbefaler man ofte at bruge SCOPE_IDENTITY() - eneste
fordel ved @@IDENTITY er at den også virker i Access og Sybase.

2)  multiple SQL statements i en enkelt SqlCommand

Det virker tilsyneladende. Men jeg turde ikke bruge det.

Dokumentationen siger:

SqlCommand.CommandText Property

The Transact-SQL statement or stored procedure to execute.

Altså SQL sætning i ental.

Jeg ville være bekymret for at det holdt op med at virke i en eller anden
fremtidig release medmindre der findes dokumentation fra Microsoft som
siger at det skal virke.

3)  SET versus SELECT

Er bare hvorvidt man gemmer i en parameter eller returnerer er result set.
Det vil jeg kalde en mindre technicality.
Avatar billede musicchart.dk Nybegynder
08. juli 2006 - 18:31 #10
Hej snepnet >> Så er det testet, og det virker super!

Men burde:
SqlParameter personId = new SqlParameter("@id", SqlDbType.Int);

Ikke være:
SqlParameter id = new SqlParameter("@id", SqlDbType.Int);

...hvis det skal passe til resten af koden?

Og må jeg gerne gøre dette?

con.Close();
int id = (int)id.Value;

.. altså lukke forbindelsen først.
Avatar billede snepnet Nybegynder
08. juli 2006 - 19:37 #11
Heh... Jo - personId går nok ikke :o)
Men hvis du kalder parameteren id - må du omdøbe her også:
int id = (int)id.Value;
(eller bliver det en redifination af id - men du kan jo kalde den hvad du vil).
Og jo... Du kan godt lukke forbindelsen før du kigge på outputparameteren.

Mht. det det med close og pæn oprydning og så'n... Så kan du pakke brug af den type af objekter ind i using's - sådan noget i denne stil:

using(SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["DemoDatabaseConnectionString1"].ConnectionString ))
using(SqlCommand command = new SqlCommand("...);set @id = SCOPE_IDENTITY()", con))
{
    SqlParameter id = new SqlParameter("@id", SqlDbType.Int);
    id.Direction = ParameterDirection.Output;
    command.Parameters.Add(id);
    con.Open();
    command.ExecuteNonQuery();
    int resultingId = (int)id.Value;
}

Compileren accepterer instantiering af objekter i using's, hvis klassen implementerer et interface der hedder IDisposable, hvilket er implementeret på de klasser i klassebiblioteket der opererer på unmanaged ressourcer.

Når objektet går out of scope (koden kommer ud over den sidste tuborg) eksekveres IDisposable's Dispose-metode på objektet, hvilket for f.eks. en databaseforbindelse vil resultere i et kald til Close().

Mvh
Avatar billede snepnet Nybegynder
08. juli 2006 - 19:43 #12
Fin post der arne - fedt at du gider den slags når spm er lukket. Jeg tror ikke umiddelbart man bør bekymre sig for om der ikke kan eksekveres flere statements med et commandobject - deres egne værktøjer genererer i hvert fald tilsvarende "flerstatements" sql.
Mvh
Avatar billede musicchart.dk Nybegynder
08. juli 2006 - 20:06 #13
Godt så :o)
Det var mest for at holde denne post så korrekt som muligt, så der er størst udbytte ved en evt. søgning.

Din forklaring giver ikke meget mening i mine øjne. Så avanceret er jeg ikke inde i C# - men det kommer jo nok en dag.
Jeg benytter en Database klasse der tager sig af åbning, kald og lukning af forbindelser osv.

Den kan håndtere de ting jeg skal bruge:
GetDataSet, GetDataTable, GetCommand, GetReader, ExecuteScalar, ExecuteNonQuery og nu også ReturnerID.

Hvilket fungerer ganske udemærket til mit behov. Men en kode kan jo næsten altid optimeres. Men som sagt, så kommer det (forhåbentligt) hen af vejen.
Avatar billede arne_v Ekspert
11. juli 2006 - 02:12 #14
snepnet>

Jeg spurgte i microsoft.public.dotnet.framework.adonet

From:        Arne Vajhøj - view profile
Date:        Sun, Jul 9 2006 7:11 pm
Groups:         microsoft.public.dotnet.framework.adonet

Is the capability of System.Data.SqlClient.SqlCommand to
execute more than one SQL statement (two SQL statements
in CommandText separated by semicolon and just one
Execute call) a supported feature that we can expect
to continue to work in the future ?

Arne

From:        Sahil Malik [MVP C#] - view profile
Date:        Sun, Jul 9 2006 11:00 pm
Groups:         microsoft.public.dotnet.framework.adonet

In SqlClient - probably yes. (I say probably because I'm not an MSFT
employee, but I haven't heard anything contrarian).

- Sahil Malik
http://www.winsmarts.com
http://blah.winsmarts.com
   
From:        Mary Chipman [MSFT] - view profile
Date:        Mon, Jul 10 2006 9:32 am
Groups:         microsoft.public.dotnet.framework.adonet

SqlClient maps to SQL Server functionality, so as long as SQL Server
continues to support multiple commands, SqlClient will :-)

--Mary
Avatar billede snepnet Nybegynder
11. juli 2006 - 09:47 #15
Hej arne :o)

Så er den vil go' nok eller?

Kommandoen bliver bare skudt direkte mode sql-serveren, og det er da mit indtryk at semikolon som batch-delimeter er en dokumenteret sql server feature.... Er det en misforståelse fra min side?

Mvh
Avatar billede arne_v Ekspert
18. juli 2006 - 04:43 #16
formentlig - jeg tror ikke at de tør ændre funktionaliteten - for meget kode vil
holde op med at virke

problem stillingen er dog lidt mere kompleks end semikolon er legal SQL

jeg eksperimenterede lidt:

                          ADO                ADO.NET                JDBC
Access                      -                    -                      -
SQLServer                  +                    +                      +
MySQL                      -                    +                      +
Avatar billede snepnet Nybegynder
18. juli 2006 - 11:26 #17
Ja det er jo et broget view, men så længe alle teknologier giver muligheden på en sql-server er det for så vidt fint nok.
Har du kigget på Oracle?
Mvh
Avatar billede arne_v Ekspert
19. juli 2006 - 02:52 #18
3 gange -
Avatar billede arne_v Ekspert
19. juli 2006 - 02:52 #19
Interesseret i DB2 eller PostgreSQL ?
Avatar billede snepnet Nybegynder
19. juli 2006 - 20:25 #20
Jeps - bestemt :o) - og tak for den med Oracle!
Mvh
Avatar billede arne_v Ekspert
23. juli 2006 - 02:57 #21
ADO                ADO.NET                JDBC
Access                    -                    -                      -
SQLServer                  +                    +                      +
MySQL                      -                    +                      +
Oracle                    -                    -                      -
DB2                        +                    +                      -
PostgreSQL                +                    +                      -
Avatar billede snepnet Nybegynder
23. juli 2006 - 16:28 #22
Fedt - mange tak arne!
Mvh
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

IT-JOB

Capgemini Danmark A/S

Open Application (Denmark)

Capgemini Danmark A/S

Management Consultant

Netcompany A/S

IT Consultant

Netcompany A/S

Network Engineer