Avatar billede prince10 Nybegynder
28. april 2005 - 15:17 Der er 17 kommentarer

kopiering via stored procs

To begin with – i’m rather newbee with this...
Case is as follow:
I have three tables: projects, projectcontent and designareas

On creating a new project there should be a possibility for copying designareas and projectcontent from an existing project.
So far that work fine with the following StoredProc

I have an one to many relation between tbl_DesignAreas and tbl_Project_Content

PK tbl_DesignAreas.areaid
FK tbl_Project_Content.designarea

CREATE PROCEDURE [dbo].[appendAll]
@NEWProjektID int,
@OLDProjektID int,
@userid int
AS

INSERT INTO dbo.tbl_DesignAreas
(DesignArea, ProjectID, description, modultreeid, Fluid, Revision_by)
SELECT DesignArea, @NEWProjektID AS ProjectID, description, modultreeid, Fluid, @uid
FROM dbo.tbl_DesignAreas
WHERE (ProjectID = @OLDProjektID)

In table tbl_DesignAreas I have an autonumber: areaid

INSERT INTO dbo.tbl_Project_Content
(componentID, Category, Quantity, ProjectID, createdby, ModultreeID,designarea)
SELECT componentID, Category, Quantity, @NEWProjektID AS projectid, @uid as createdby, ModultreeID, designarea
FROM dbo.tbl_Project_Content
WHERE (ProjectID = @OLDProjektID)
GO
Now in the second part of the stored proc it copies the rows from tbl_project_content correct except that designarea is copied as is with it’s old values, and here I miss the relationship.
Is it possible to have the value designarea to correspond to the newly created (autonumber) id’s from the first part of the stored proc.

Sincerely Uffe
Avatar billede ldanielsen Nybegynder
28. april 2005 - 15:55 #1
Yes indeed

@@IDENTITY to the rescue ...
Avatar billede ldanielsen Nybegynder
28. april 2005 - 15:59 #2
CREATE PROCEDURE [dbo].[appendAll]
@NEWProjektID int,
@OLDProjektID int,
@userid int,
@newIdent int
AS

INSERT INTO dbo.tbl_DesignAreas
(DesignArea, ProjectID, description, modultreeid, Fluid, Revision_by)
SELECT DesignArea, @NEWProjektID AS ProjectID, description, modultreeid, Fluid, @uid
FROM dbo.tbl_DesignAreas
WHERE (ProjectID = @OLDProjektID)
SET @newIdent = @@IDENTITY

INSERT INTO dbo.tbl_Project_Content
(componentID, Category, Quantity, ProjectID, createdby, ModultreeID,designarea)
SELECT componentID, Category, Quantity, @NEWProjektID AS projectid, @uid as createdby, ModultreeID, @newIdent
FROM dbo.tbl_Project_Content
WHERE (ProjectID = @OLDProjektID)
GO


When a new row is added, and an identity is created, it is stored in @@IDENTITY. Check Books Online for further details
Avatar billede prince10 Nybegynder
28. april 2005 - 15:59 #3
Ja - det burde kunne lade sig gøre...
nogen der kan hjælpe med en løsning...
Avatar billede ldanielsen Nybegynder
28. april 2005 - 16:00 #4
Sig mig, behøver jeg ikke bruge mit skoleengelsk?? :o)
Avatar billede prince10 Nybegynder
28. april 2005 - 16:01 #5
Fint nok - men den tager vel kun den seneste kopierede række og giver newIdent  hertil - jeg har flere rækker, der skal kopieres. - Så det må vel være noget med noget loop...
Avatar billede prince10 Nybegynder
28. april 2005 - 16:03 #6
NOpe jeg er skam pæredansk...
Avatar billede ldanielsen Nybegynder
28. april 2005 - 16:11 #7
Så må du bruge en cursor, Jeg skitserer, så kan du måske selv se fidusen.


DECLARE curOldAreas cursor for

SELECT DesignArea, description, modultreeid, Fluid FROM dbo.tbl_DesignAreas
WHERE (ProjectID = @OLDProjektID)

open curOldAreas

FETCH NEXT .....

WHILE ...
BEGIN

  INSERT INTO dbo.tbl_DesignAreas
    (DesignArea, ProjectID, description, modultreeid, Fluid, Revision_by) ....

  SET @newIdent = @@IDENTITY

  INSERT INTO dbo.tbl_Project_Content
    (componentID, Category, Quantity, ProjectID, createdby, ModultreeID,designarea)
    SELECT componentID, Category, Quantity, @NEWProjektID AS projectid,
      @uid as createdby, ModultreeID, @newIdent
      FROM dbo.tbl_Project_Content
      WHERE (ProjectID = @OLDProjektID)


  FETCH NEXT ...
END


close curOldAreas
DEALLOCATE curOldAreas
Avatar billede prince10 Nybegynder
28. april 2005 - 23:33 #8
Hm... - ser ud til at være noget i den retning jeg skal have fat i:
Men jeg kan ikke helt se fidusen ( er ikke ligefrem en haj til det her, og har en deadline på mandag, hvor jeg skal fremvise systemet jeg er ved at lave... - Kan du se hvad der yderligere mangler - har prøvet at tilpasse den til de aktuelle data:
Får en:
Server: Msg 156, Level 15, State 1, Procedure appendAll, Line 15
Incorrect syntax near the keyword 'BEGIN'.
Server: Msg 156, Level 15, State 1, Procedure appendAll, Line 19
Incorrect syntax near the keyword 'SET'.
- når jeg prøver at parse den...

CREATE PROCEDURE [dbo].[appendAll]
@NEWProjektID int,
@OLDProjektID int,
@uid int,
@newIdent int
AS

DECLARE curOldAreas cursor for
SELECT DesignArea,  @NEWProjektID AS ProjectID, description, modultreeid, Fluid, @uid
FROM dbo.tbl_DesignAreas
WHERE (ProjectID = @OLDProjektID)
open curOldAreas
FETCH NEXT
WHILE
BEGIN

  INSERT INTO dbo.tbl_DesignAreas
    (DesignArea, ProjectID, description, modultreeid, Fluid, Revision_by)
  SET @newIdent = @@IDENTITY
  INSERT INTO dbo.tbl_Project_Content
    (componentID, Category, Quantity, ProjectID, createdby, ModultreeID,designarea)
    SELECT componentID, Category, Quantity, @NEWProjektID AS projectid, @uid as createdby,
    ModultreeID, @newIdent
      FROM dbo.tbl_Project_Content
      WHERE (ProjectID = @OLDProjektID)
  FETCH NEXT
END

close curOldAreas
DEALLOCATE curOldAreas
Avatar billede prince10 Nybegynder
29. april 2005 - 08:48 #9
Hvis jeg sætter:
...
DECLARE curOldAreas cursor for
SELECT DesignArea,  @NEWProjektID AS ProjectID, description, modultreeid, Fluid, @uid
FROM dbo.tbl_DesignAreas
WHERE (ProjectID = @OLDProjektID)
open curOldAreas
FETCH NEXT
/*Indsat @@FETCH_STATUS = 0*/
WHILE @@FETCH_STATUS = 0
BEGIN ...
Får jeg kun en fejl med SET når jeg parser den:
Incorrect syntax near the keyword 'SET'.

Hvad mangler der lige mere?
Avatar billede ldanielsen Nybegynder
29. april 2005 - 10:44 #10
Åhja, men du FETCH'er ikke rigtigt, troede du kendte til cursors. Jeg deklarerer 4 nye variabler; @DesignArea int, @description varchar(200),  @modultreeid int, @Fluid bit, ret det lige så de får de rigtige datatyper:

CREATE PROCEDURE [dbo].[appendAll]
@NEWProjektID int,
@OLDProjektID int,
@uid int,
@newIdent int
AS

DECLARE @DesignArea int,
  @description varchar(200),
  @modultreeid int,
  @Fluid bit


DECLARE curOldAreas cursor for
SELECT DesignArea, description, modultreeid, Fluid
  FROM dbo.tbl_DesignAreas
  WHERE (ProjectID = @OLDProjektID)

open curOldAreas
FETCH NEXT from curOldAreas into @DesignArea, @description, @modultreeid, @Fluid
WHILE @@FETCH_STATUS = 0
BEGIN

  INSERT INTO dbo.tbl_DesignAreas
    (DesignArea, ProjectID, description, modultreeid, Fluid, Revision_by)
  VALUES
    (@DesignArea, @NEWProjektID, @description, @modultreeid, @Fluid, @uid)
  SET @newIdent = @@IDENTITY
  INSERT INTO dbo.tbl_Project_Content
    (componentID, Category, Quantity, ProjectID, createdby, ModultreeID, designarea)
    SELECT componentID, Category, Quantity, @NEWProjektID, @uid,
    ModultreeID, @newIdent
      FROM dbo.tbl_Project_Content
      WHERE (ProjectID = @OLDProjektID)
  FETCH NEXT from curOldAreas into @DesignArea, @description, @modultreeid, @Fluid

END

close curOldAreas
DEALLOCATE curOldAreas
Avatar billede prince10 Nybegynder
29. april 2005 - 12:28 #11
hm... - se lige den her:
Og nej jeg kendte absolut intet til cursors... *S*

CREATE PROCEDURE [dbo].[appendAllFetch]
@NEWProjektID int,
@OLDProjektID int,
@uid int,
@newIdent int
AS

DECLARE
  @DesignArea varchar(50),
  @projectID int,
  @description varchar(100),
  @modultreeid int,

DECLARE curOldAreas cursor for
SELECT DesignArea, projectID, description, modultreeid
  FROM dbo.tbl_DesignAreas
  WHERE (ProjectID = @OLDProjektID)

open curOldAreas
FETCH NEXT from curOldAreas into @DesignArea, @projectID, @description, @modultreeid
WHILE @@FETCH_STATUS = 0
BEGIN
  INSERT INTO dbo.tbl_DesignAreas
    (DesignArea, ProjectID, description, modultreeid)
  VALUES
    (@DesignArea, @NEWProjektID, @description, @modultreeid)
  SET @newIdent = @@IDENTITY
  INSERT INTO dbo.tbl_Project_Content
    (componentID, Category, Quantity, ProjectID, ModultreeID, designarea)
    SELECT componentID, Category, Quantity, @NEWProjektID, ModultreeID, @newIdent
      FROM dbo.tbl_Project_Content
      WHERE (ProjectID = @OLDProjektID)
  FETCH NEXT from curOldAreas into @DesignArea, @projectID, @description, @modultreeid
END
close curOldAreas
DEALLOCATE curOldAreas
GO

På min tabel tbl_DesignAreas har jeg en primary key (auto) AreaID - skal den med nogen steder?
Avatar billede ldanielsen Nybegynder
29. april 2005 - 12:33 #12
Den er jo "med", for i linien SET @newIdent = @@IDENTITY henter du den nylig indsatte værdi ud.

I øvrigt er der en fejl, for @newIdent int skal ikke stå før AS som den gør, det er jo en lokal variabel. Sæt den sammen med de andre dklarationer:

DECLARE
  @DesignArea varchar(50),
  @projectID int,
  @description varchar(100),
  @modultreeid int,
  @newIdent int


Endnu en fejl, der var komma efter @modultreeid int, og det skulle der ikke have været, men nu skal der, hvis du forstår hvad jeg mener :o)
Avatar billede prince10 Nybegynder
29. april 2005 - 13:15 #13
Den er sgu tæt på nu - syntaksfejler ikke længere...
Rækker i tbl_designareas oprettes korrekt.
men der oprettet nu rækker i tbl_projectContent i anden - altså eks.  tre rækker i tbl_projectContent kopieres til 9 nye rækker.
eks:
tbl_designareas:
ProjectID    AreaID  designarea
322            378    area1
322            379    area2
322            380    area3

Tbl_ProjectContent:
Rækker der kopieres fra:

uniqueID  ProjectID  designarea  modultreeid
599            74          374        3
600            74          375        3
498            74          219        3

Giver:

uniqueID  ProjectID  designarea  modultreeid
604            322          377        3
605            322          377        3
606            322          377        14
607            322          378        3
608            322          378        3
609            322          378        14
610            322          379        3
611            322          379        3
612            322          379        14

Hvad sker der lige...
Avatar billede ldanielsen Nybegynder
29. april 2005 - 16:11 #14
Den her del er gal:

INSERT INTO dbo.tbl_Project_Content
    (componentID, Category, Quantity, ProjectID, ModultreeID, designarea)
    SELECT componentID, Category, Quantity, @NEWProjektID, ModultreeID, @newIdent
      FROM dbo.tbl_Project_Content
      WHERE (ProjectID = @OLDProjektID)

Den inserter data valgt fra sig selv, der mangler vist et forbehold (WHERE et eller andet)

Har ikke tid nu ...
Avatar billede prince10 Nybegynder
04. maj 2005 - 23:03 #15
INSERT INTO dbo.tbl_Project_Content
    (componentID, Category, Quantity, ProjectID, ModultreeID, designarea)
    SELECT componentID, Category, Quantity, @NEWProjektID, ModultreeID, @newIdent
      FROM dbo.tbl_Project_Content
      WHERE (ProjectID = @OLDProjektID and modultreeid = @modultreeid)
 
Tilføjet: and modultreeid = @modultreeid og det funker - Tusind tak for hjælpen ...
Avatar billede ldanielsen Nybegynder
06. maj 2005 - 20:08 #16
Selv tak
Avatar billede the_bma_man Nybegynder
22. november 2005 - 23:14 #17
point?
Lukke?
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
Computerworld tilbyder specialiserede kurser i database-management

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