Welcome to Sign in | Help
in Search

update pe un field

Last post 01-25-2008, 1:32 PM by noface. 15 replies.
Page 1 of 2 (16 items)   1 2 Next >
Sort Posts: Previous Next
  •  01-21-2008, 5:25 PM 3805

    update pe un field

    salut

    am o tabela cu 100 de inregustrari sa zicem. as vrea ca pe fieldul "compare" sa inserez o concatenare de mai mult fielduri.

    problema e ca nu stiu cum sa fac asta automat pt fiecare inregistrare, in functie de nr de nr de field-uri prezente, dinamica ca numar fiid

    pe metada de mai jos, imi cicleaza indefinit si scrie informatia din prima inregistrare in toate campurile, e ca si cum nu sare la indexul urmator

    set ANSI_NULLS ON
    set QUOTED_IDENTIFIER ON
    go

    alter procedure insert_string_compare
    as
    set nocount on
    declare @_string_long varchar(8000),
        @_index int,
        @_numeCh varchar(50),
        @_prenumeCh varchar(50),
        @_functieCh varchar(50),
        @_departamentCh varchar (50),
        @_managerCh varchar (50),
        @_user_AD varchar (50),
        @_index_p1 int,
        @_index_count int

    declare @extract_cursor cursor
    set @extract_cursor=cursor local for
    ......etc etc...
    fetch next ...etc...

    WHILE (@@FETCH_STATUS <> -1)
        BEGIN
          IF (@@FETCH_STATUS <> -1)
          BEGIN

      set @_string_long=@_numeCh+@_prenumeCh+@_functieCh+@_departamentCh+@_managerCh+@_user_AD
      update preluate_last set compare= @_string_long where [index]=@_index
      set @_index=@_index+1
      
      end
    end

     

  •  01-21-2008, 7:13 PM 3807 in reply to 3805

    Re: update pe un field

    Problema se poate rezolva folosind camp calculat (computed column) care face apel la o functie  (UDF); un site interesant
    Gheorghe Ciubuc,SQL Server Influencer, MCP(SQL 2000), MCTS (SQL Server 2005) , OCA(Oracle 9i), Sybase(Brainbench)
  •  01-21-2008, 8:53 PM 3809 in reply to 3805

    Re: update pe un field

    Iti lipseşte un fetch next din while:
    fetch next ...etc...

    WHILE (@@FETCH_STATUS <> -1)
    BEGIN
    IF (@@FETCH_STATUS <> -1)
    BEGIN

    set @_string_long=@_numeCh+@_prenumeCh+@_functieCh+@_departamentCh+@_managerCh+@_user_AD
    update preluate_last set compare= @_string_long where [index]=@_index
    set @_index=@_index+1
    end

    fetch next ...
    end
  •  01-21-2008, 9:00 PM 3810 in reply to 3809

    Re: update pe un field

    De asemenea, ce sens are IF-ul din WHILE daca conditia este indentică ?
    Cursorul poate fi FORWARD_ONLY (implicit DYNAMIC) si modificarile le poti realiza folosind comanda UPDATE ... WHERE CURRENT OF ...

    Daca toate campurile se regasesc in aceeasi tabela atunci poti apela la o solutie de tipul:
    CREATE TABLE [dbo].[Angajat](
      [Id] [int] NOT NULL,
      [Nume] [varchar](50) NOT NULL,
      [Prenume] [varchar](50) NOT NULL,
      [Departament] [varchar](50) NOT NULL,
      [ToText] AS (((([Nume]+' ')+[Prenume])+', dep:')+[Departament]),
    CONSTRAINT [PK_Angajat] PRIMARY KEY CLUSTERED
    (
      [Id] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY]
    --eventual definesti campul calculat ToText ca fiind
    PERSISTED
    GO

    INSERT INTO Angajat VALUES (1,'ION','IONESCU','FINANCIAR')
    INSERT INTO Angajat VALUES (2,'POPA','POPESCU','FINANCIAR')
    INSERT INTO Angajat VALUES (3,'VASILE','VASILESCU','CONTABILITATE')

    GO

    SELECT * FROM Angajat

    In situatia in care campurile Nume, Prenume, Departament se regasesc in tabele diferite (de ex. ai o tabela Angajat si o alta tabela Departament) atunci poti să defineşti o tabelă virtuală / vedere (en. view) folosind comanda CREATE VIEW.
  •  01-21-2008, 10:34 PM 3811 in reply to 3810

    Re: update pe un field

    Si eu inclin pentru "computed column". Poti crea coloana ca "PERSISTED" (vezi BOL). Atentie la nulabilitatea coloanelor din care calculezi si la cazurile in care vrei sa inserezi in tabel si omiti din lista de INSERT coloana calculata.
  •  01-22-2008, 9:37 AM 3812 in reply to 3805

    Re: update pe un field

    noface:

    am o tabela cu 100 de inregustrari sa zicem. as vrea ca pe fieldul "compare" sa inserez o concatenare de mai mult fielduri.



    De ce vrei să faci asta? Vrei cumva să compari această coloană cu o coloană similară din altă tabelă, în scopul de a sincroniza doar rândurile care au fost modificate ? Dacă da, ar trebui să iei în considerare că:
    1. o simplă concatenare nu îţi sesizează anumite schimbări (de exemplu, din Prenume="Ion Gheorghe" şi Nume="Popescu" în Prenume="Ion" şi Nume="Gheorghe Popescu")
    2. o să fie dificil să iei în considerare tipul de date al fiecărei coloane
    3. rezultatul va ocupa un spaţiu destul de mare.

    Eu îţi sugerez să foloseşti funcţia CHECKSUM(*), care îţi furnizează un int provenit dintr-un checksum al tuturor coloanelor din rândul respectiv. Bineînţeles că şi această funcţie poate furniza acelaşi rezultat la mai multe rânduri diferite (în definitiv, acest lucru e o caracteristică a oricărei funcţie de hashing), dar este puţin probabil să se întâmple acest lucru cu două rânduri care au sens. Şi dacă vrei să fie şi mai puţin probabil, poţi să foloseşti funcţia HASHBYTES (disponibilă doar începând cu SQL Server 2005), dar aceasta necesită un argument de tip varchar, nvarchar sau varbinary (deci trebuie oricum să concatenezi valorile respective înainte).

    Dacă totuşi este vital ca această comparaţie să se efectueze exact (adică să sesizeze absolut orice modificări), atunci eu îţi recomand să compari fiecare coloană (ţinând cont şi de posibilitatea de a exista NULL-uri), după ce în prealabil ai făcut un join pe o coloană indexată (cum ar fi un PRIMARY KEY nemodificabil sau o coloană calculată cu funcţia CHECKSUM).

    Răzvan
  •  01-22-2008, 11:25 AM 3814 in reply to 3812

    Re: update pe un field

    Daca vb. de sincronizarea datelor (sau chiar a structurii) a două tabele se poate utiliza începând cu SQL2005 utilitarul tablediff:
    BOL URL ms-help://MS.SQLCC.v9/MS.SQLSVR.v9.en/sqlcmpt9/html/3c3cb865-7a4d-4d66-98f2-5935e28929fc.htm

    Exemplu:
    --///////////////////////////////////////////////////////////////////
    USE test
    GO

    --tabela sursa
    CREATE TABLE [dbo].[Angajat](
      [Id] [int] PRIMARY KEY,
      [Nume] [varchar](50) NOT NULL,
      [Prenume] [varchar](50) NOT NULL,
      [Departament] [varchar](50) NOT NULL
    )
    GO

    INSERT INTO Angajat VALUES (1,'ION','IONESCU','FINANCIAR')
    INSERT INTO Angajat VALUES (2,'POPA','POPESCU','FINANCIAR')
    INSERT INTO Angajat VALUES (3,'VASILE','VASILESCU','CONTABILITATE')
    GO

    SELECT * FROM Angajat
    GO
    --///////////////////////////////////////////////////////////////////

    --///////////////////////////////////////////////////////////////////
    USE testdep
    GO

    --tabela destinatie
    SELECT *
    INTO Angajat
    FROM Test.dbo.Angajat
    GO

    SELECT * FROM Angajat
    GO
    --///////////////////////////////////////////////////////////////////

    --///////////////////////////////////////////////////////////////////
    --TEST
    --Etapa [1] inserare, modificare, stergeri in tabela sursa test.dbo.Angajat
    --<etapa_1>
    USE test
    GO

    INSERT INTO Angajat VALUES (4,'ACE','DETECTIVUL','ZUZU')
    INSERT INTO Angajat VALUES (5,'LUI','PESTE','ZUZU')
    UPDATE Angajat SET Departament = 'ZUZU' WHERE Id = 1
    DELETE FROM Angajat WHERE Id = 3
    GO
    --</etapa_1>

    --Etapa [2] executie tablediff pentru generarea scriptului de sincronizare
    /*
    D:\Documents and Settings\bgdn>cd\
    D:\>cd Program Files\Microsoft SQL Server\90\COM
    D:\Program Files\Microsoft SQL Server\90\COM>TableDiff -sourceserver "(local)\SQLEXPRESS,1433" -sour
    cedatabase "test" -sourcetable "Angajat" -destinationserver "(local)\SQLEXPRESS,1433" -destinationda
    tabase "testdep" -destinationtable "Angajat" -f "d:\script.sql"

    User-specified agent parameter values:
    -sourceserver (local)\SQLEXPRESS,1433
    -sourcedatabase test
    -sourcetable Angajat
    -destinationserver (local)\SQLEXPRESS,1433
    -destinationdatabase testdep
    -destinationtable Angajat
    -f c:\script.sql

    Table [test].[dbo].[Angajat] on (local)\SQLEXPRESS,1433 and Table [testdep].[dbo].[Angajat] on (loca
    l)\SQLEXPRESS,1433 have 4 differences.
    Fix SQL written to c:\script.sql.
    Err Id Col
    Mismatch 1 Departament
    Dest. Only 3
    Src. Only 4
    Src. Only 5
    The requested operation took 0.4375 seconds.

    D:\Program Files\Microsoft SQL Server\90\COM>
    */



    --Etapa [3] Executie script de sincronizare d:\script.sql in Management Studio sau sqlcmd
    -- Host: (local)\SQLEXPRESS,1433
    -- Database: [testdep]
    -- Table: [dbo].[Angajat]
    USE testdep
    GO

    UPDATE [dbo].[Angajat] SET [Departament]='ZUZU' WHERE [Id] = 1
    DELETE FROM [dbo].[Angajat] WHERE [Id] = 3
    INSERT INTO [dbo].[Angajat] ([Departament],[Id],[Nume],[Prenume]) VALUES ('ZUZU',4,'ACE','DETECTIVUL')
    INSERT INTO [dbo].[Angajat] ([Departament],[Id],[Nume],[Prenume]) VALUES ('ZUZU',5,'LUI','PESTE')
    GO


    --Etapa [3] verificare inregistrarilor din cele 2 tabele
    --<etapa_3>
    SELECT * FROM test.dbo.Angajat
    SELECT * FROM testdep.dbo.Angajat
    --</etapa_3>
    --///////////////////////////////////////////////////////////////////

    Cu putin efort, sincronizarea poate fi automatizata.
  •  01-22-2008, 11:30 AM 3815 in reply to 3812

    Re: update pe un field

    rsocol:
    noface:

    am o tabela cu 100 de inregustrari sa zicem. as vrea ca pe fieldul "compare" sa inserez o concatenare de mai mult fielduri.



    1. o simplă concatenare nu îţi sesizează anumite schimbări (de exemplu, din Prenume="Ion Gheorghe" şi Nume="Popescu" în Prenume="Ion" şi Nume="Gheorghe Popescu")

    quite true, la aceasta posibilitate nu ma gandisem. hashbytes vad ca e o alternativa interesanta, nu stiam de ea, dar se explica, sunt inca incepator :)

    mulltumesc tuturor pt sfaturi

  •  01-24-2008, 2:50 PM 3822 in reply to 3815

    Re: update pe un field

    ok, ca sa nu mai deschid alt topic, scriu tot aici..
    acum,am 5 proceduri care individual fac cate ceva
    as vrea sa le pun sa ruleze intr-o anumita ordine , dar numai dupa ce cea anterioara termina de rumegat ce a avut de facut.. nu prea stiu cum.. pot sa pun un parametru de output sau cum le apelez? direct din procedura sau altfel? mentionez ca individual ele fac niste prelucrari pe baza de date, deci nu trebuie sa-si trimita date intre ele
  •  01-24-2008, 3:05 PM 3823 in reply to 3822

    Re: update pe un field

    noface:
    ok, ca sa nu mai deschid alt topic, scriu tot aici..
    acum,am 5 proceduri care individual fac cate ceva
    as vrea sa le pun sa ruleze intr-o anumita ordine , dar numai dupa ce cea anterioara termina de rumegat ce a avut de facut.. nu prea stiu cum.. pot sa pun un parametru de output sau cum le apelez? direct din procedura sau altfel? mentionez ca individual ele fac niste prelucrari pe baza de date, deci nu trebuie sa-si trimita date intre ele

    create proc ProcAll
    as
    begin
    exec proc1
    exec proc2
    exec proc3
    exec proc4
    exec proc5
    end

    Ignat Andrei
    http://serviciipeweb.ro/iafblog
  •  01-24-2008, 3:12 PM 3824 in reply to 3822

    Re: update pe un field

    Procedurile stocate pot avea parametrii tip OUTPUT pentru a returna diverse valori.
    De asemenea intr-o procedura stocata se poate folosi instructiunea RETURN pentru a returna o valoare INT.

    Poti sa executi o procedura stocata folosind EXECUTE.

    Poti sa verifici daca o anumita linie dintr-un script SQL a fost executata cu succes folosind
    @@ERROR (SQL2000)
    sau / si
    TRY ... CATCH (SQL2005).

    Exemplu pt. SQL2005 (o solutie):
    CREATE PROCEDURE proc6
      @param1 INT,
      @param2 INT,
      @param3 INT,
      @param4 INT,
      @param5 INT,
      @eroare INT OUTPUT
    AS
      DECLARE @rezultat INT
      
      EXECUTE @rezultat = procedura1 @param1
      IF ( @rezultat != 0 )
      BEGIN
        SET @eroare = @rezultat
        RETURN 1 --eroare la executia procedurii 1
      END

      EXECUTE @rezultat = procedura2 @param2
      IF ( @rezultat != 0 )
      BEGIN
        SET @eroare = @rezultat
        RETURN 2 --eroare la executia procedurii 2
      END

      --executia celoralante proceduri

      EXECUTE @rezultat = procedura5 @param5
      IF ( @rezultat != 0 )
      BEGIN
        SET @eroare = @rezultat
        RETURN 5 --eroare la executia procedurii 5
      END
      
      RETURN 0 --executia celor 5 proceduri s-a incheiat cu succes


    Fiecare din cele 5 proceduri pot fi definite astfel (o posibila solutie):
    CREATE PROCEDURE procedura1
      @p INT
    AS

    BEGIN TRY
      
      SELECT ___
      INSERT ___
      UPDATE ___  

      RETURN 0
    END TRY
    BEGIN CATCH
      RETURN ERROR_NUMBER()
    END CATCH


    Folosesti si tranzactii ?
  •  01-24-2008, 3:47 PM 3825 in reply to 3824

    Re: update pe un field

    NB: si in procedura "principala" , procedura şase se putea utiliza TRY ... CATCH plus
    ERROR_PROCEDURE().
  •  01-25-2008, 12:09 PM 3826 in reply to 3825

    Re: update pe un field

    imi cer scuze anticipat dc sunt "a pain in the a**" cu intrebarile mele, dar experimentez f mult perioada asta.. besides, raspunsuri mai la obiect si detaliate ca aici n-am intalnit nicaieri :)

    so, acum am alta gogoasa.

    vreau sa scriu intr-un fisier ldf datele prelucrate anterior

    problema este ca nu stiu cu sa apendez o linie noua in fisierul ala, in asa fel incat sa nu folosesc cate 1 variabila pt fiecare linie,ca ar fi vreo 40:)

    eu am incercat ceva de genul

    set @o1='echo dn: CN='+@p_prenume+' '+@p_nume+', OU=Test1, DC=test, DC=home >> c:\dsq\ldifimport.ldf'
    set @o1=@o1+'echo kkkkkk >> c:\dsq\ldifimport.ldf '
      exec master..xp_cmdshell @o1

    dar imi scrie pe aceasi linie,in continuare

    am mai incercat cu +CHAR(13) si CHAR(10) dar fara succes

     

    edit: sry, i got it, mi-a venit ideea dupa ce am postat :)

    set @o1='echo dn: CN='+@p_prenume+' '+@p_nume+', OU=Test1, DC=test, DC=home >> c:\dsq\ldifimport.ldf'exec master..xp_cmdshell @o1
    set @o1=@o1+'echo kkkkkk >> c:\dsq\ldifimport.ldf '
      exec master..xp_cmdshell @o1

    etc...

    dar tot nu pot sa scriu o linie goala blank, care e necesara in fisier

  •  01-25-2008, 12:45 PM 3827 in reply to 3826

    Re: update pe un field

    Pentru a transfera datele intr-un fisier poti folosi in
    SQL2000 > DTS (utilitarul dtsrun.exe) şi / sau bcp
    iar in
    SQL2005 > SSIS (utilitarul dtexec.exe) şi / sau bcp.

    Detaliază puţin mai mult structura fişierul în care vrei să exporţi datele precizând şi tabela sau interogarea din care sunt preluate datele.
  •  01-25-2008, 12:49 PM 3828 in reply to 3826

    Re: update pe un field

    Dacă vrei să adaugi o linie goală la un fişier text, poţi să faci:
    EXEC master..xp_cmdshell 'echo.>>fisier.txt'
    Adică pui un punct imediat după echo şi nimic altceva.

    Pentru cei care sunt puţin surprinşi de extensia LDF a fişierului tău, bănuiesc că, în acest context, un fişier LDF nu este ce ştim noi (adică SQL Server Transaction Log file), fiind vorba de fapt de "LDAP Data Interchange Format".

    Pe de altă parte, ar fi bine să deschizi un thread nou pentru fiecare subiect, pentru că ceea ce scriem acum n-are nicio legătură cu "update pe un field".

    Răzvan
Page 1 of 2 (16 items)   1 2 Next >
View as RSS news feed in XML
Powered by Community Server (Commercial Edition), by Telligent Systems