|
update pe un field
Last post 01-25-2008, 1:32 PM by noface. 15 replies.
-
01-21-2008, 5:25 PM |
-
noface
-
-
-
Joined on 12-11-2007
-
-
db_owner
-
-
|
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 |
-
ggciubuc
-
-
-
Joined on 03-18-2006
-
Bucharest
-
sysadmin
-
-
|
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 |
-
B_gd_n[ ]Sahlean
-
-
-
Joined on 07-17-2007
-
Bucuresti
-
sysadmin
-
-
|
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 |
-
B_gd_n[ ]Sahlean
-
-
-
Joined on 07-17-2007
-
Bucuresti
-
sysadmin
-
-
|
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 |
-
01-22-2008, 9:37 AM |
-
rsocol
-
-
-
Joined on 10-03-2006
-
Bucuresti
-
sysadmin
-
-
|
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 |
-
B_gd_n[ ]Sahlean
-
-
-
Joined on 07-17-2007
-
Bucuresti
-
sysadmin
-
-
|
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 |
-
noface
-
-
-
Joined on 12-11-2007
-
-
db_owner
-
-
|
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 |
-
01-24-2008, 3:05 PM |
-
ignatandrei
-
-
-
Joined on 11-17-2006
-
Bucuresti
-
sysadmin
-
-
|
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 |
-
01-24-2008, 3:47 PM |
-
01-25-2008, 12:09 PM |
-
noface
-
-
-
Joined on 12-11-2007
-
-
db_owner
-
-
|
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 |
-
01-25-2008, 12:49 PM |
Page 1 of 2 (16 items)
1
|
|
|