mboost-dp1

Mysql "hente" id efter insert


Gå til bund
Gravatar #1 - Jonasee
2. dec. 2008 19:50
Hej

Jeg ville høre om det er muligt at "hente" det id/identety der er blevet oprette ved en insert.

Jeg kan jo lave en selecte, men er det muligt at få det fra en return eller noget ligne?

Venlig hilsen
Jonas
Gravatar #2 - arne_v
2. dec. 2008 20:10
#1

Det ligger i LAST_INSERT_ID() og kan enten hentes med en SELECT, bruges direkte i efterfølgende INSERT eller kan returneres fra en SP.

Visse sprog/database API bl.a. Java JDBC og PHP mysql/mysqli giver mulighed for at hente det uden eksplicit SQL.
Gravatar #3 - arne_v
2. dec. 2008 20:23
#2

Hvis det er SQLServer bruger du SCOPE_IDENTITY(). Og f.eks. Oracle er lidt anderledes da de bruge sequence fremfor auto increment.
Gravatar #4 - Jonasee
2. dec. 2008 20:24
ok, tak for det.
Gravatar #5 - mindzero
3. dec. 2008 06:56
Hvis du bruger PHP kan du bruge den her funktion:
http://dk.php.net/mysql_insert_id
Gravatar #6 - apocs
15. dec. 2008 22:45
Der kan opstå et problem ved brugen af LAST_INSERT_ID() - Hvis der er mange der bruger systemet på én gang, kan en anden bruger måske nå at indsætte en post, inden koden hos første bruger når at blive afviklet helt.

LAST_INSERT_ID() henter den sidste post, der er indsat i en autoincrement tabel.

Det absolut sikreste ville jo være, nu hvor du alligevel laver en select, at lave det med de oplysninger du lige har sat ind.

Men så længe der måske bare er en håndfuld der bruger systemet, skulle der ikke være de store problemer.
Gravatar #7 - arne_v
15. dec. 2008 22:52
#6

Forkert.

LAST_INSERT_ID() er sidst indsatte værdi for den brugte connection. Den påvirkes ikke af hvad der laves med andre connections.
Gravatar #8 - apocs
16. dec. 2008 13:30
#7

Korrekt... Mig der var en smule hurtig der...

Fra MySQL Reference Manual:

Each client will receive the last inserted ID for the last statement that client executed.
Gravatar #9 - Windcape
23. dec. 2008 18:58
Visse sprog/database API bl.a. Java JDBC og PHP mysql/mysqli giver mulighed for at hente det uden eksplicit SQL.
Mig bekendt kan JDBC kun gøre det på visse databaser. MS SQL gemmen ODBC tillader det ihvertfald ikke hos mig.

Det afhænger nok mere af ens database-adapter end sproget selv.

Desuden er det ikke "SELECT @@IDENTITY" i MS SQL?
Gravatar #10 - arne_v
23. dec. 2008 19:17
#9

Kravene for at kunne det er er Java 1.4 eller nyere og en JDBC 3.0 compliant JDBC driver.

Jeg har aldrig prøvet med SQLServer. Men udfra årstal og hvad man kan læse på Microsofts web site vil jeg antage at Microsofts JDBC driver til SQLServer 2000 kun er JDBC 2.1 compliant mens den til SQLServer 2005 er JDBC 3.0 compliant.

Det burde derfor virke med SQLServer 2005 og driver til samme (eller SQLServer 2008 - jeg mener ikke at der er en ny JDBC driver til den, hvis der er så er den sikker JDBC 4.0 compliant).

Jeg har ingen anelse om FreeTDS JDBC driverens JDBC compliance.

Hvilke versioner har du forsøgt med ?

(hvis 2005 + 2005 ikke virker for dig, så kan jeg godt prøve at teste hos mig i aften)
Gravatar #11 - arne_v
23. dec. 2008 19:18
#9

SELECT @@IDENTITY

vil virke, men jeg vil klart anbefale:

SELECT SCOPE_IDENTITY()
Gravatar #12 - arne_v
23. dec. 2008 19:20
#11

Og inden nogen spørger:

simpel INSERT i tabel x
identity key genereret i tabel x
=>
@@IDENTITY returnerer identity fra tabel x
SCOPE_IDENTITY() returnerer identity fra tabel x

simpel INSERT i tabel x
identity key genereret i tabel x
insert trigger på tabel x laver en ny INSERT i tabel y
identity key genereret i tabel y
=>
@@IDENTITY returnerer identity fra tabel y
SCOPE_IDENTITY() returnerer identity fra tabel x



Gravatar #13 - arne_v
24. dec. 2008 03:48
#10

Hos mig giver:

    public static void test(String driver, String url, String usr, String pw) throws Exception {
Class.forName(driver);
Connection con = DriverManager.getConnection(url, usr, pw);
DatabaseMetaData dmd = con.getMetaData();
System.out.println("Database = " + dmd.getDatabaseProductName() + " " + dmd.getDatabaseProductVersion());
System.out.println("JDBC driver = " + dmd.getDriverName() + " " + dmd.getDriverVersion());
System.out.println("JDBC compliance = " + dmd.getJDBCMajorVersion() + "." + dmd.getJDBCMinorVersion());
Statement stmt = con.createStatement();
stmt.executeUpdate("CREATE TABLE garbage (k INTEGER IDENTITY(777,1) PRIMARY KEY, v VARCHAR(50))");
stmt.executeUpdate("INSERT INTO garbage (v) VALUES ('foobar')", Statement.RETURN_GENERATED_KEYS);
ResultSet rs = stmt.getGeneratedKeys();
if(rs.next()) {
System.out.println(rs.getInt(1));
}
stmt.executeUpdate("DROP TABLE garbage");
stmt.close();
con.close();
}


følgende output:

Database = Microsoft SQL Server 9.00.1399
JDBC driver = Microsoft SQL Server 2005 JDBC Driver 1.0.809.102
JDBC compliance = 3.0
777
Gravatar #14 - arne_v
24. dec. 2008 03:53
#13

Det virker ikke med SQLServer 2000 og dens JDBC driver.

Det virker fint med SQLServer 2000 og JDBC driveren til 2005.
Gravatar #15 - Flemhans
24. dec. 2008 05:32
Det er nogle gode IDeer der bliver fremlagt her, men det vil være nemmest hvis man skrev hvilket PROG sprog der er tale om.


Gravatar #16 - Windcape
24. dec. 2008 12:25
#15

SQL , og så lidt snakkeri om db-adapters in Java (JDBC).

#arne_v

Ok, så må det være grunden da stmt.getGeneratedKeys() ikke var tilladt på den adapter jeg prøvede med.

Standard 1.5 odbc adapter vil jeg tro, uden at have kigget nærmere på det, da tingene normalt bare virkede uden videre kode.

Rart at lære lidt så :) Også mht. post #12
Gravatar #17 - arne_v
24. dec. 2008 13:55
Windcape (16) skrev:

Standard 1.5 odbc adapter vil jeg tro, uden at have kigget nærmere på det, da tingene normalt bare virkede uden videre kode.


Da vel ikke JDBC-ODBC bridgen og en ODBC driver til SQLServer ?

ODBC er generelt ikke specielt attraktivt. Men SUN's JDBC-ODBC bridge er noget af det værste crap der nogensinde er kodet !
Gravatar #18 - Windcape
24. dec. 2008 14:01
Så giver det meget mere mening :-)
Gravatar #19 - arne_v
24. dec. 2008 14:15
#18

Det er generelt problemer med ODBC og fejlmeddelser - disse er ofte uforståelige.

ODBC performer ofte ringere end andre database API'er.

Det er grund nok til at du f.eks. i .NET vil bruge SqlClient fremfor ODBC.

Men JDBC-ODBC bridgen er langt værre. Bl.a. er den ikke thread safe. Brug den i en multithreaded app og du får random fejl i kaldene.

Som det fremgår af tidligere indlæg så er der 2 JDBC drivere for SQLServer:
- Microsofts egen
- FreeTDS

Af princip foretrækker jeg at bruge driveren fra database leverandøren, men der er også mange som bruger FreeTDS driveren.

(hvis du har brugt SQLServer fra PHP kørende på *nix, så kender du FreeTDS, da mssql extension bruger FreeTDS på ikke-Windows platforme)

Gravatar #20 - arne_v
24. dec. 2008 14:21
#19

Både Microsoft og FreeTDS driverne er type 4 drivere d.v.s. pure Java indtil de rammer socket level - så ingen native database kode.
Gå til top

Opret dig som bruger i dag

Det er gratis, og du binder dig ikke til noget.

Når du er oprettet som bruger, får du adgang til en lang række af sidens andre muligheder, såsom at udforme siden efter eget ønske og deltage i diskussionerne.

Opret Bruger Login