[SQL]- Probleem met DELETE FROM WHERE SELECT-combo

Pagina: 1
Acties:
  • 114 views sinds 30-01-2008
  • Reageer

  • Tsjipmanz
  • Registratie: Oktober 2000
  • Laatst online: 13-05 14:52

Tsjipmanz

Der Rudi ist da

Topicstarter
Zit al n tijd te klooien met een SQL-query, misschien dat jullie t zien! :) Gebruik ColdFusion en een Access--database. Ik denk echter dat het deze keer ligt aan de query. Dit is m
code:
1
2
3
4
5
6
7
8
9
DELETE FROM SelectMatches 
WHERE (InschrijfID, BedrID) IN 
(  SELECT SelectMatches.InschrijfID, SelectMatches.BedrID 
   FROM rp_cv_stat, CV_Persoonsgegevens, SelectMatches
   WHERE ((CV_Persoonsgegevens.CV_datum < rp_cv_stat.datumtijd)
         AND (rp_cv_stat.InschrijfID = SelectMatches.InschrijfID)
         AND (CV_Persoonsgegevens.InschrijfID = SelectMatches.InschrijfID)         
           AND (rp_cv_stat.bedrID = SelectMatches.bedrID))
)

Dit levert als foutmelding
You have written a subquery that can return more than one field without using the EXISTS reserved word in the main query's FROM clause. Revise the SELECT statement of the subquery to request only one field
Hmmm, niet zo mooi. Als ik de IN vervang door EXISTS krijg ik een syntax-error als resultaat.
Dit, terwijl de SUB-query toch probleemloos een resultaat oplevert. Wat doe ik fout? :?

There's no such thing as a mistake, just happy accidents - Bob Ross
Relaxte muziek: altijd okee!
- Soulseek rulez -


Verwijderd

EXISTS IN dan ? kweenie klinkt wel fun :D

  • Tsjipmanz
  • Registratie: Oktober 2000
  • Laatst online: 13-05 14:52

Tsjipmanz

Der Rudi ist da

Topicstarter
Op dinsdag 12 februari 2002 16:36 schreef Zoepnek het volgende:
EXISTS IN dan ? kweenie klinkt wel fun :D
Nope :(
Tried that already!

There's no such thing as a mistake, just happy accidents - Bob Ross
Relaxte muziek: altijd okee!
- Soulseek rulez -


Verwijderd

t gaat fout in je hoofd kweeries from clausule dus daar moet exists tussen ofzo al lang geen sql meer gedaan

  • Woudloper
  • Registratie: November 2001
  • Niet online

Woudloper

« - _ - »

Niet mijn specialiteit, maar zoiets:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
DELETE FROM SelectMatches 
WHERE (InschrijfID) IN 
           (SELECT SelectMatches.BedrID 
            FROM rp_cv_stat, CV_Persoonsgegevens, SelectMatches
            WHERE ((CV_Persoonsgegevens.CV_datum < rp_cv_stat.datumtijd)
                AND (rp_cv_stat.InschrijfID = SelectMatches.InschrijfID)
                AND (CV_Persoonsgegevens.InschrijfID = SelectMatches.InschrijfID)          
                AND (rp_cv_stat.bedrID = SelectMatches.bedrID))
            )
OR   (BedrID) IN
           (SELECT SelectMatches.BedrID 
            FROM rp_cv_stat, CV_Persoonsgegevens, SelectMatches
            WHERE ((CV_Persoonsgegevens.CV_datum < rp_cv_stat.datumtijd)
                AND (rp_cv_stat.InschrijfID = SelectMatches.InschrijfID)
                AND (CV_Persoonsgegevens.InschrijfID = SelectMatches.InschrijfID)          
                AND (rp_cv_stat.bedrID = SelectMatches.bedrID))
            )

  • hvdwal
  • Registratie: Maart 2001
  • Laatst online: 17-08-2021
Volgens mij moet je bij een Where In clausule slechts 1 veld opgeven. Anders gewoon meerdere Where In clausules. Dus bijvoorbeeld:

Delete From Dittum
Where DittemID1 In (Select DattumID From Dattum)
Or DittemID2 In (Select DattumID From Dattum)

Ik roep maar wat, maar als ik maar de foutmelding kijk moet je daar volgens mij het probleem zoeken. Pruts ze :?

Woudloper was me ff voor... maar da's wat ik ongeveer zoiets bedoel ja ;)

  • Tsjipmanz
  • Registratie: Oktober 2000
  • Laatst online: 13-05 14:52

Tsjipmanz

Der Rudi ist da

Topicstarter
Hmmm was op zich wel een idee, maar die wist alles. En ik heb ook al een AND geprobeerd maar die wist niks.

Ik zal de zaak nog wel s goed bekijken en de query weloverwogen opnieuw maken.

Thanx anyway!

There's no such thing as a mistake, just happy accidents - Bob Ross
Relaxte muziek: altijd okee!
- Soulseek rulez -


Verwijderd

Zoooo tsjipke dus toch serieus aan het werk! :)

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 12-09 21:31

Janoz

Moderator Devschuur®

!litemod

Op woensdag 13 februari 2002 10:35 schreef mixologist het volgende:
Zoooo tsjipke dus toch serieus aan het werk! :)
Kun jij nog wat van leren :).. Beetje op kosten van de gemeenschap tegen de wensen van het systeembeheer in Win2000 instaleren he :)

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • VisionMaster
  • Registratie: Juni 2001
  • Laatst online: 18-07 20:32

VisionMaster

Security!

Zoals hierboven 2 of meer maal is beschreven is het niet de bedoeling om 2 of meer velden in je subselect te gebruiken.

Sterker nog, het is niet toegestaan volgens de standaard SQL-syntax (wordt gebruikt in 80% van de dbms-en).

AnyWay...

Je bent verplicht te splitsen. Dus met een and of or moet je dit fixen.
Of welligt een union binnen de subselectie.

Have FuN... :)

I've visited the Mothership @ Cupertino


  • Tsjipmanz
  • Registratie: Oktober 2000
  • Laatst online: 13-05 14:52

Tsjipmanz

Der Rudi ist da

Topicstarter
Heb er nu al meerdere uren inzitten maar het lukt op dit moment gewoon NIET! :( Ik geef niet graag op maar het schip is op dit moment redelijk gestrand.
Misschien dat iemand in een moment van helderheid mij ff een tip kan geven, ik zal het probleem hier uiteenzetten:

Okee er zijn 3 tabellen involved:

SelectMatches - deze bevat een inschrijfID en een bedrID (mensen wiens CV naar een bepaald
bedrijf gestuurd moeten worden)

rp_cv_stat - hier staan ook een inschrijfID en een bedrijfsID, plus een veld datumtijd (op welk
moment is welke CV naar welk bedrijf gemaild)

CV_Persoonsgegevens - de enige relevante velden hier zijn inschrijfID (eigenaar CV) en datum
(aanmaak/wijzigingsdatum)


Wat er nu moet gebeuren is het volgende:

Uit SelectMatches moeten DIE combinaties BedrijfsID/InschrijfID gewist worden, waarvoor geldt
dat de CV is aangemaakt/gewijzigd NA het tijdstip dat hij naar het bedrijf is gemaild.

Oftewel, er moet gelden:

CV_Persoonsgegevens.CV_datum > rp_cv_stat.datumtijd

Om die entries met een SELECT-statemnt te krijgen is niet zo moeilijk:
code:
1
2
3
4
5
6
7
SELECT SelectMatches.InschrijfID, SelectMatches.BedrID, FROM rp_cv_stat, CV_Persoonsgegevens,
SelectMatches
WHERE (  (CV_Persoonsgegevens.CV_datum > rp_cv_stat.datumtijd)
     AND (rp_cv_stat.InschrijfID = CV_Persoonsgegevens.InschrijfID)
     AND (rp_cv_stat.InschrijfID = SelectMatches.InschrijfID)
     AND (rp_cv_stat.bedrID = SelectMatches.bedrID)
     )

Om deze entries te DELETEn echter is een ander verhaal... Zoals in mijn post boven duidelijk is geworden lukt het niet om dit rechtstreeks te koppelen aan een DELETE FROM-statement.

Ook de opsplitsing die geadviseerd is levert niet het gewenste resultaat op.

Ik ben de wanhoop nabij! :'(
Anyone?

There's no such thing as a mistake, just happy accidents - Bob Ross
Relaxte muziek: altijd okee!
- Soulseek rulez -


Verwijderd

constraints inbouwen in je datamodel is waarschijnlijk de enige manier.

Zoek eens op 'on delete cascade'

Verwijderd

Ik denk dat je hier de fout ingaat omdat dit kan resulteren in meer als 1 record

CV_Persoonsgegevens.CV_datum < rp_cv_stat.datumtijd

Dit werkt bijvoorbeeld wel..
code:
1
2
3
4
5
6
7
8
9
10
11
<cfquery datasource="#dsn#" name="unit_access">
SELECT id, label
FROM units
WHERE id IN 
     (SELECT unit
    FROM unit_roles
      WHERE id IN 
      (SELECT unit_role
       FROM user_roles
       WHERE user = #Cfusion_Decrypt(url.user, cryptokey)#))
</cfquery>

  • justmental
  • Registratie: April 2000
  • Niet online

justmental

my heart, the beat

Ik ken de mogelijkheden van Access niet maar probeer dit eens:
code:
1
2
3
4
5
6
7
8
DELETE FROM SelectMatches
WHERE EXISTS (SELECT 'dummy'
   FROM rp_cv_stat, CV_Persoonsgegevens
   WHERE ((CV_Persoonsgegevens.CV_datum < rp_cv_stat.datumtijd)
         AND (rp_cv_stat.InschrijfID = SelectMatches.InschrijfID)
         AND (CV_Persoonsgegevens.InschrijfID = SelectMatches.InschrijfID)
             AND (rp_cv_stat.bedrID = SelectMatches.bedrID))
)

[edit]excuses, layout was #$%[/edit]

Who is John Galt?


  • Tsjipmanz
  • Registratie: Oktober 2000
  • Laatst online: 13-05 14:52

Tsjipmanz

Der Rudi ist da

Topicstarter
Op vrijdag 15 februari 2002 11:24 schreef Gordijnstok het volgende:
Ik denk dat je hier de fout ingaat omdat dit kan resulteren in meer als 1 record
Dat is idd het geval, maar dat zou je toch kunnen omzeilen met een DISTINCT?
Ik denk dat de kern van mijn probleem is terug te brengen tot het volgende:

Stel dat
code:
1
2
3
SELECT A, B
FROM Tabel
WHERE voorwaarden

een bepaald resultaat oplevert, hoe kan ik dat bepaalde resultaat koppelen aan een DELETE query.
code:
1
2
3
4
5
DELETE FROM Tabel
WHERE 
  A = (SELECT A FROM Tabel WHERE Voorwaarden)
AND
  B = (SELECT B FROM Tabel WHERE Voorwaarden)

wist namelijk gewoon teveel.

btw, ik werk met ColdFusion, denk jij (GordijnStok) dat een QofQ ook handig zou kunnen zijn in dit geval?

There's no such thing as a mistake, just happy accidents - Bob Ross
Relaxte muziek: altijd okee!
- Soulseek rulez -


Verwijderd

uit de access help: (zoeken op 'on delete cascade')

Dit is echt de enige manier om dit probleem op te lossen. Als je eenmaal de materie snapt dan werkt het perfect!!!!

Why should I use cascading updates or cascading deletes?
For relationships in which referential integrity is enforced, you can specify whether you want Microsoft Access to automatically cascade update and cascade delete related records. If you set these options, delete and update operations that would normally be prevented by referential integrity rules are allowed. When you delete records or change primary key values in a primary table, Microsoft Access makes necessary changes to related tables to preserve referential integrity.

If you select the Cascade Update Related Fields check box when defining a relationship, any time you change the primary key of a record in the primary table, Microsoft Access automatically updates the primary key to the new value in all related records. For example, if you change a customer's ID in the Customers table, the CustomerID field in the Orders table is automatically updated for every one of that customer's orders so that the relationship isn't broken. Microsoft Access cascades updates without displaying any message.

Note If the primary key in the primary table is an AutoNumber field, setting the Cascade Update Related Fields check box will have no effect, because you can't change the value in an AutoNumber field.

If you select the Cascade Delete Related Records check box when defining a relationship, any time you delete records in the primary table, Microsoft Access automatically deletes related records in the related table. For example, If you delete a customer record from the Customers table, all the customer's orders are automatically deleted from the Orders table (this includes records in the Order Details table related to the Orders records). When you delete records from a form or datasheet with the Cascade Delete Related Records check box selected, Microsoft Access warns you that related records may also be deleted. However, when you delete records using a delete query, Microsoft Access automatically deletes the records in related tables without displaying a warning.

For information on how to edit an existing relationship and set referential integrity, click .

For information on how to define a new relationship, click .

  • Tsjipmanz
  • Registratie: Oktober 2000
  • Laatst online: 13-05 14:52

Tsjipmanz

Der Rudi ist da

Topicstarter
Op vrijdag 15 februari 2002 11:46 schreef hajee het volgende:
uit de access help: (zoeken op 'on delete cascade')
zal t ff doorlezen, tx

There's no such thing as a mistake, just happy accidents - Bob Ross
Relaxte muziek: altijd okee!
- Soulseek rulez -


  • gevoelig
  • Registratie: Februari 2002
  • Laatst online: 25-08 09:31
Eenvoudige oplossing:

Sla de resultaten van en de query en de sub query('s) op in een var en vergelijk de resultaten buiten SQL.

Greetnz Gevoelig |:(

Buiten is het koud en guur. Gisteren was het warmer dan vandaag. Maar dat kan ook aan mij liggen...


  • DigiK-oz
  • Registratie: December 2001
  • Laatst online: 13-09 13:38
Je kan, zoals reeds aangegeven, maar 1 veld opgeven bij WHERE.....IN.

Kan je die velden aan elkaar knopen ? Iets van :

WHERE (InschrijfID||BedrID) IN
( SELECT SelectMatches.InschrijfID||SelectMatches.BedrID
FROM

waar dan || de 'concatenation' operator is.

Whatever


  • Tsjipmanz
  • Registratie: Oktober 2000
  • Laatst online: 13-05 14:52

Tsjipmanz

Der Rudi ist da

Topicstarter
Op vrijdag 15 februari 2002 11:54 schreef sjis het volgende:
Je kan, zoals reeds aangegeven, maar 1 veld opgeven bij WHERE.....IN.

Kan je die velden aan elkaar knopen ? Iets van :

WHERE (InschrijfID||BedrID) IN
( SELECT SelectMatches.InschrijfID||SelectMatches.BedrID
FROM

waar dan || de 'concatenation' operator is.
Pff die oplossing zou erg "vies" zijn. Is InschrijfID dan 1 en Bedr 11 of andersom. Dat gaat dus niet werken.

There's no such thing as a mistake, just happy accidents - Bob Ross
Relaxte muziek: altijd okee!
- Soulseek rulez -


Verwijderd

Op vrijdag 15 februari 2002 11:51 schreef gevoelig het volgende:
Eenvoudige oplossing:

Sla en de query en de sub query('s) op in een var en vergelijk de resultaten buiten SQL.

Greetnz Gevoelig |:(
Makkelijk is anders, gebruik gebruik gewoon de mogelijkheden van je DBMS. Dit is veel netter en sneller. En je programmatuur is hierdoor ook eenvoudiger. Heeft hier echt niemand van referentiele integriteit gehoord??

Verwijderd

Op vrijdag 15 februari 2002 11:40 schreef Tsjipmanz het volgende:

[..]

Stel dat
code:
1
2
3
SELECT A, B
FROM Tabel
WHERE voorwaarden

een bepaald resultaat oplevert, hoe kan ik dat bepaalde resultaat koppelen aan een DELETE query.
code:
1
2
3
4
5
DELETE FROM Tabel
WHERE 
  A = (SELECT A FROM Tabel WHERE Voorwaarden)
AND
  B = (SELECT B FROM Tabel WHERE Voorwaarden)

wist namelijk gewoon teveel.

btw, ik werk met ColdFusion, denk jij (GordijnStok) dat een QofQ ook handig zou kunnen zijn in dit geval?
DELETE FROM mijntabel
WHERE a IN (
SELECT column
FROM tabel1
WHERE id = integer
)
AND b IN (
SELECT column
FROM tabel2
WHERE id = integer
)

Een QofQ is niet bruikbaar voor updates of deletes :) Het is niets anders als een query in het RAM geheugen plaatsen nl. en geen DB toegang.

Dan zou je dus het volgende krijgen

<cfquery datasource="#dsn#" name="MyQuery" CachedWithin="#CreateTimeSpan(dagen,uren,minuten,seconden)#>
SELECT A, B
FROM Tabel
WHERE voorwaarden
</cfquery>

<cfquery dbtype="query" name="MyQuery2">
DELETE FROM MyQuery
WHERE A IN (
SELECT A
FROM MyQuery
)
AND B IN (
SELECT B
FROM MyQuery
)
</cfquery>

En dat kan dus niet.. je voert bewerkingen uit op een stukje geheugen ipv de database :) Snappie

  • DigiK-oz
  • Registratie: December 2001
  • Laatst online: 13-09 13:38
Op vrijdag 15 februari 2002 11:57 schreef Tsjipmanz het volgende:

[..]

Pff die oplossing zou erg "vies" zijn. Is InschrijfID dan 1 en Bedr 11 of andersom. Dat gaat dus niet werken.
Nooit gezegd dat die oplossing netjes is >:) .

Een teken (spatie o.i.d) tussen de twee velden plakken in je query voorkomt genoemd probleem overigens.

Whatever


  • Goodielover
  • Registratie: November 2001
  • Laatst online: 18-08 11:34

Goodielover

Only The Best is Good Enough.

Hier is de oplossing.
Je moet er een gecorrelleerde sub-query van maken.

Het was sowieso onnodig om de selectmatches tabel ook in de sub-select te gebruiken.
code:
1
2
3
4
5
6
7
8
9
10
DELETE FROM SelectMatches 
WHERE EXISTS 
     (SELECT 1 
    FROM   rp_cv_stat r
        ,CV_Persoonsgegevens c
    WHERE  c.CV_datum < r.datumtijd
    AND    c.InschrijfID = r.InschrijfID
    AND    r.InschrijfID = SelectMatches.InschrijfID
    AND    r.bedrID = SelectMatches.bedrID
     )

Verwijderd

Wat je nu dus hebt kan ik eigenlijk anders geprogged zo neer zetten:

<cfquery datasource="#dsn#" name="MijnQuery">
SELECT a, b
FROM tabel
</cfquery>

<cfloop query="MijnQuery">
<cfquery datasource="#dsn#">
DELETE FROM anderetabel
WHERE a = #a#
AND b = #b#
</cfquery>
</cfloop>

  • Tsjipmanz
  • Registratie: Oktober 2000
  • Laatst online: 13-05 14:52

Tsjipmanz

Der Rudi ist da

Topicstarter
Ik durf zo ongeveer mn gezicht hier nooit meer te laten zien |:(

Zijn nu meerdere oplossingen gegeven al die wel klopten waaronder o.a. die van Goodielover. Ik had zelf ook al een goeie oplossing, ware het niet dat ik dacht ie niet goed was. |:(

Er was namelijk een CV waarvoor gold dat:

CV_datum < datumtijd
maar ook
CV_datum > datumtijd

omdat deze CV twee keer in de tabel stond. Omdat de CV zowel VOOR als NA het wijzigen was gemaild voldeed deze dus aan de eis dat hij NA het wijzigen was gemaild en is hij dus -volkomen terecht- gewist, terwijl ik in de veronderstelling was dat hij had moeten blijven staan. |:(

Ik denk dat Goodielover de meest elegante oplossing heeft gegeven. Ik heb niet alle adviezen uitgeprobeerd maar ik kan nu in elk geval weer verder.

Allemaal erg veel dank en ik ga me dit weekend eens ff diep schamen! :)

There's no such thing as a mistake, just happy accidents - Bob Ross
Relaxte muziek: altijd okee!
- Soulseek rulez -


  • justmental
  • Registratie: April 2000
  • Niet online

justmental

my heart, the beat

Op vrijdag 15 februari 2002 13:15 schreef Tsjipmanz het volgende:
Ik durf zo ongeveer mn gezicht hier nooit meer te laten zien |:(
There's no such thing as a mistake, just happy accidents - Bob Ross
;)

Who is John Galt?


Verwijderd

Op vrijdag 15 februari 2002 12:08 schreef Goodielover het volgende:
Hier is de oplossing.
Je moet er een gecorrelleerde sub-query van maken.

Het was sowieso onnodig om de selectmatches tabel ook in de sub-select te gebruiken.
code:
1
2
3
4
5
6
7
8
9
10
DELETE FROM SelectMatches 
WHERE EXISTS 
     (SELECT 1 
    FROM   rp_cv_stat r
        ,CV_Persoonsgegevens c
    WHERE  c.CV_datum < r.datumtijd
    AND    c.InschrijfID = r.InschrijfID
    AND    r.InschrijfID = SelectMatches.InschrijfID
    AND    r.bedrID = SelectMatches.bedrID
     )
juist,dat is de oplossing!

/edit: beetje laat ;)
Pagina: 1