---
title: "Hämta ID?"
type: "forum-thread"
url: "https://www.webforum.nu/amne/databaser-sql/171116-hämta-id"
topic: "Databaser & SQL"
topic_url: "https://www.webforum.nu/amne/databaser-sql"
author: "Guldstrand"
published: "2008-04-27T19:22:09.000Z"
updated: "2008-04-29T07:53:50.000Z"
replies: 17
views: 819
page: 1
pages: 1
language: "sv-SE"
site: "webForum — webforum.nu"
rights: "Upphovsrätten till varje inlägg tillhör dess författare."
attribution: "Citera som: webForum, https://www.webforum.nu/amne/databaser-sql/171116-hämta-id"
---

# Hämta ID?

## #1 — Guldstrand, 2008-04-27T19:22Z

Jag försöker att skapa ett enklare forum, men jag vet inte hur jag får med 'amne_id' till mixtabellen (amne_inlagg).
Just nu har jag bara satt amne_id till '0'.

Detta är koden för att spara ett nytt ämne i databasen:

```php
$amne = db_escape($_POST['amne']);
$av = db_escape($_POST['av']); 
$ip = db_escape($_SERVER['REMOTE_ADDR']); 

$text = db_escape($_POST['text']);
$fran = db_escape($_POST['fran']);

$sql = "INSERT INTO amnen(

amne,  
av,  
ip, 
datum) 

VALUES(

'$amne',  
'$av',  
'$ip', 
NOW())"; 

mysql_query($sql) or die (mysql_error());

$sql2 = "INSERT INTO inlagg(

text,  
av,  
ip, 
fran, 
datum) 

VALUES(

'$text',  
'$av',  
'$ip', 
'$fran', 
NOW())"; 

mysql_query($sql2) or die (mysql_error());

$inid = mysql_insert_id();

$sql3 = "INSERT INTO amne_inlagg(

amne_id, 
inlagg_id) 

VALUES(
'0',
'$inid')"; 

mysql_query($sql3) or die (mysql_error());

	header("Location: posta_amne.php");
}
```

Tacksam för hjälp.
Uppskattar även tips på hur man kan optimera -och/eller korta ner koden.

Permalänk: https://www.webforum.nu/p/171116

## #2 — Fredde Mannen, 2008-04-27T19:35Z

Det beror väl på vad amne_id är för något och var vi kan få det ifrån.

Går man in under ett ämne för att skriva ett inlägg, då har du säkert ämnets id i url:en, då kan du spara ned med $\_GET i ett "hidden"-input-fält i formuläret för inlägget och skicka med det i postningen av inlägget!

Permalänk: https://www.webforum.nu/p/2103540

## #3 — Peter S, 2008-04-27T20:00Z

Det finns olika sätt att lösa det på. Ett är att använda samma sätt som du hämtar 'inid' på (om amne_id är ett autonummerfält vill säga). Dock behöver du lägga samtliga dessa operationer i en transaktion, så att du inte riskerar att skapa konstigheter i databasen.

Vilken storage engine använder du?

Permalänk: https://www.webforum.nu/p/2103547

## #4 — Guldstrand, 2008-04-27T20:04Z

> **Peter S skrev:**
>
> Det finns olika sätt att lösa det på. Ett är att använda samma sätt som du hämtar 'inid' på (om amne_id är ett autonummerfält vill säga). Dock behöver du lägga samtliga dessa operationer i en transaktion, så att du inte riskerar att skapa konstigheter i databasen.
> 
> Vilken storage engine använder du?

Jag använder MyISAM på samtliga tabeller.
Ja, amne_id har "auto_increment".

Permalänk: https://www.webforum.nu/p/2103549

## #5 — Guldstrand, 2008-04-27T20:22Z

Löste det såhär:

```php
$amne = db_escape($_POST['amne']);
$av = db_escape($_POST['av']); 
$ip = db_escape($_SERVER['REMOTE_ADDR']); 

$text = db_escape($_POST['text']);
$fran = db_escape($_POST['fran']);

$sql = "INSERT INTO amnen(

amne,  
av,  
ip, 
datum) 

VALUES(

'$amne',  
'$av',  
'$ip', 
NOW())"; 

mysql_query($sql) or die (mysql_error()); 

$aid = mysql_insert_id();

$sql2 = "INSERT INTO inlagg(

text,  
av,  
ip, 
fran, 
datum) 

VALUES(

'$text',  
'$av',  
'$ip', 
'$fran', 
NOW())"; 

mysql_query($sql2) or die (mysql_error());

$inid = mysql_insert_id();

$sql3 = "INSERT INTO amne_inlagg(

amne_id, 
inlagg_id) 

VALUES(
'$aid',
'$inid')"; 

mysql_query($sql3) or die (mysql_error());
```

Finns det ett bättre sätt att lösa detta på?

Permalänk: https://www.webforum.nu/p/2103553

## #6 — Peter S, 2008-04-27T20:36Z

Ja, du vill ha dem i en transaktion. Men eftersom MyISAM inte gillar det får du använda LOCK TABLES:

```
lock tables amnen write;
insert into amnen ...
$aid = ...
unlock tables;
lock tables inlagg write;
insert into inlagg ...
$inid = ...
unlock tables;
insert into amne_inlagg ...
```

Permalänk: https://www.webforum.nu/p/2103555

## #7 — Guldstrand, 2008-04-27T20:38Z

> **Peter S skrev:**
>
> Ja, du vill ha dem i en transaktion. Men eftersom MyISAM inte gillar det får du använda LOCK TABLES:
>
>
> ```
> lock tables amnen write;
> insert into amnen ...
> $aid = ...
> unlock tables;
> lock tables inlagg write;
> insert into inlagg ...
> $inid = ...
> unlock tables;
> insert into amne_inlagg ...
> ```

Nu förstår jag ingenting.   :r 
Varför går det inte att ha det så som jag postade ovan?

För/nackdelar?

Permalänk: https://www.webforum.nu/p/2103556

## #8 — Peter S, 2008-04-27T21:02Z

Titta på dessa två rader:

```
$sql = "INSERT INTO amnen(

amne,  
av,  
ip,
datum)

VALUES(

'$amne',  
'$av',  
'$ip',
NOW())";
...
$aid = mysql_insert_id();
```

$aid kommer bara att innehålla korrekt värde om insert_id körs direkt efter INSERT. Men det finns ju faktiskt en möjlighet att det är flera besökare på sidan, och då kan ordningen på frågorna se ut enligt följande:

```
INSERT INTO //besökare 1
INSERT INTO //besökare 2
$aid = mysql_insert_id() //besökare 1
$aid = mysql_insert_id() //besökare 2
```

$aid kommer alltså att innehålla samma värde för båda besökarna - det är inte bra.

Permalänk: https://www.webforum.nu/p/2103562

## #9 — Guldstrand, 2008-04-27T21:04Z

Hmm, ok...
Hur löser jag då detta på enklaste sätt?

Permalänk: https://www.webforum.nu/p/2103564

## #10 — Peter S, 2008-04-27T21:15Z

Genom att låsa tabellerna i fråga precis innan skrivning (INSERT) och låsa upp dem igen direkt efter selektering (mysq_insert_id), så hindrar du andra från att skriva till dem under den kritiska tiden. Se inlägg #6.

Permalänk: https://www.webforum.nu/p/2103567

## #11 — spango, 2008-04-28T06:29Z

> **Peter S skrev:**
>
> $aid kommer alltså att innehålla samma värde för båda besökarna - det är inte bra.

Nej, det kommer de inte, eftersom last_insert_id fungerar per anslutning.

Permalänk: https://www.webforum.nu/p/2103597

## #12 — Type, 2008-04-28T06:48Z

hmm. hur är det nu det funkar? Pratar vi mysql_insert_id?

Funkar den per anslutning eller per databas? måste vi låsa tabeller eller ej?

Man vill ju inte gärna missa en sån här grej. det är ju svårt att felsöka...

Permalänk: https://www.webforum.nu/p/2103598

## #13 — spango, 2008-04-28T07:36Z

PHP-funktionen mysql_insert_id() fungerar på samma sätt som MySQL-funktionen LAST_INSERT_ID() och funkar per anslutning.

Permalänk: https://www.webforum.nu/p/2103607

## #14 — Type, 2008-04-28T10:30Z

Med andra ord har Peter S fel?

Permalänk: https://www.webforum.nu/p/2103658

## #15 — spango, 2008-04-28T10:50Z

Ja, angående hur mysql_insert_id funkar. Att låsa tabellerna ger en ganska ond inverkan på skalbarheten, dessutom. Sen stämmer det iofs att du egentligen vill ha dina inserts i en transaktion, om en misslyckas är alla meningslösa, men det kanske varken är sannolikt att någon av dem felar eller dödsviktigt att det funkar klockrent i ett forum (eftersom det bara lär vara under ganska exceptionella omständigheter som några funkar och inte gör det).

Permalänk: https://www.webforum.nu/p/2103663

## #16 — Guldstrand, 2008-04-28T13:10Z

Tack för svaret "Spango", misstänkte att det var ok att göra som jag gjorde.

Använder mig av detta:

```php
$amne = db_escape($_POST['amne']);
$av = db_escape($_POST['av']); 
$ip = db_escape($_SERVER['REMOTE_ADDR']); 

$text = db_escape($_POST['text']);
$fran = db_escape($_POST['fran']);

$sql = "INSERT INTO amnen(

amne,  
av,  
ip, 
datum) 

VALUES(

'$amne',  
'$av',  
'$ip', 
NOW())"; 

mysql_query($sql) or die (mysql_error()); 

$aid = mysql_insert_id();

$sql2 = "INSERT INTO inlagg(

text,  
av,  
ip, 
fran, 
datum) 

VALUES(

'$text',  
'$av',  
'$ip', 
'$fran', 
NOW())"; 

mysql_query($sql2) or die (mysql_error());

$inid = mysql_insert_id();

$sql3 = "INSERT INTO amne_inlagg(

amne_id, 
inlagg_id) 

VALUES(
'$aid',
'$inid')"; 

mysql_query($sql3) or die (mysql_error());
```

Går det att korta ner alt. optimera koden ovan?
Tacksam för alla tips/förslag.

Permalänk: https://www.webforum.nu/p/2103702

## #17 — Peter S, 2008-04-28T16:26Z

Beaten   :p 

Intressant citat från TFM:

> For LAST_INSERT_ID(), the most recently generated ID is maintained in the server on a per-connection basis. It is not changed by another client. It is not even changed if you update another AUTO_INCREMENT column with a non-magic value (that is, a value that is not NULL and not 0). Using LAST_INSERT_ID() and AUTO_INCREMENT columns simultaneously from multiple clients is perfectly valid. Each client will receive the last inserted ID for the last statement that client executed.

Permalänk: https://www.webforum.nu/p/2103750

## #18 — spango, 2008-04-29T07:53Z

> **Guldstrand skrev:**
>
> Går det att korta ner alt. optimera koden ovan?
> Tacksam för alla tips/förslag.

Tabellen amne_inlagg får mig att fundera lite. Du insertar värdena som strängar när det rimligen borde vara heltal (två ID:n). Sen undrar jag lite varför du öht har den tabellen, alls? Vore det inte vettigare att bara ha ett ämnes-ID i inläggstabellen? Jag misstänker att du inte har ett många-till-många-förhållande mellan ämne och inlägg, så det borde ju räcka med att inläggen pekar på det ämne de är postade i.

Permalänk: https://www.webforum.nu/p/2103827

---

Tråden på webben: https://www.webforum.nu/amne/databaser-sql/171116-hämta-id
