none
mehrere SP in einer? RRS feed

  • Frage

  • Hallo,

    habe verschiedene parametriserte SP für versch. Komponenten. D.H. ich führe 4x hintereinander die gleiche SP mit geänderten Parameters aus.

    Ist es sinnvoller die SP so zu schreiben dass sie für alle Komponenten gilt und nur 1x ausgeführt werden muss? Und wie funktioniert das genau?

    Hier meine SP:

    USE [injektormontage]
    GO
    /****** Object: StoredProcedure [dbo].[setStatus]  Script Date: 12/24/2010 22:12:51 ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    
    Create PROCEDURE [dbo].[setStatus]
     @tblname	nvarchar(127),
     @field		nvarchar(127),
     @ident		nvarchar(10),
     @status	nvarchar(2),
     @debug		bit = 0 AS
    	Declare @sql nvarchar(1000)
    
    	set @sql = 'Update ' + @tblname + ' Set Status = ' + @status + ' Where ' + @field + ' = ' + @ident
    
    	IF @debug = 1 PRINT @sql
    	EXEC sp_executesql @sql
    	
    SET NOCOUNT OFF
    

    Gruß Andreas

    Freitag, 24. Dezember 2010 21:25

Antworten

  • Hallo Andreas,

    hier ist ein Beispiel, das zeigt, wie man innerhalb einer SP mehrere Tabellen aktualisieren kann:

    use tempdb
    go
    --Testtabellen
    create table t1([status] nvarchar(2),col12 nvarchar(10))
    create table t2([status] nvarchar(2),col22 nvarchar(10))
    go
    --Testdaten
    insert into t1 values('11','11')
    insert into t2 values('22','22')
    go
    --Usertype
    create type type1 as table
    (
    	tblname		nvarchar(127),
    	field		nvarchar(127),
    	ident		nvarchar(10),
    	status		nvarchar(2)
    )
    go
    --SP SetStatus
    create proc SetStatus
    	@values_for_update type1 readonly,
    	@debug		bit = 0
    as
    begin
    	set nocount on;
    
    	declare @sql nvarchar(max)
    
    	select @sql = (coalesce(@sql,'') + 'update ' + tblname + ' set status = ''' + [status] + ''' where ' + field + ' = ' + ident + ';')
    	from @values_for_update
    	
    	if @debug = 1 print @sql
    
    	exec (@sql)
    end
    go
    --Eingabeparameter @values_for_update
    declare @values_for_update type1
    insert into @values_for_update values
    ('t1','col12','11','00'),
    ('t2','col22','22','00')
    --rufft die SP auf
    exec [dbo].[setStatus] @values_for_update=@values_for_update,@debug=1
    go
    --zeigt aktualisierte Daten an
    select * from t1
    select * from t2
    go
    --löscht alle Testobjekte
    drop table t1, t2;
    drop proc [dbo].[setStatus];
    drop type type1;
    go
    

    Gruß Yury
    Samstag, 25. Dezember 2010 15:20
  • Hallo Andreas,
    nicht alles was machbar ist, ist auch wirklich gut. Der zweite Ansatz von Yury ist wahrscheinlich der bessere, wobei ich die Zugriffe auf verschiedene Tabellen durch entsprechende Prozeduren trennen würde um optimale Performance, Übersichtlichkeit und Berechtigungsvergaben hinzubekommen.

    Ergänzend dazu empfehle ich noch folgenden Artikel:
    http://www.insidesql.org/blogs/frankkalis/2004/07/16/dynamisches-sql-fluch-und-segen

    Einen schönen Tag noch,
    Christoph


    Microsoft SQL Server MVP
    http://www.insidesql.org/blogs/cmu

    Montag, 3. Januar 2011 07:21

Alle Antworten

  • Hallo Andreas,

    hier ist ein Beispiel, das zeigt, wie man innerhalb einer SP mehrere Tabellen aktualisieren kann:

    use tempdb
    go
    --Testtabellen
    create table t1([status] nvarchar(2),col12 nvarchar(10))
    create table t2([status] nvarchar(2),col22 nvarchar(10))
    go
    --Testdaten
    insert into t1 values('11','11')
    insert into t2 values('22','22')
    go
    --Usertype
    create type type1 as table
    (
    	tblname		nvarchar(127),
    	field		nvarchar(127),
    	ident		nvarchar(10),
    	status		nvarchar(2)
    )
    go
    --SP SetStatus
    create proc SetStatus
    	@values_for_update type1 readonly,
    	@debug		bit = 0
    as
    begin
    	set nocount on;
    
    	declare @sql nvarchar(max)
    
    	select @sql = (coalesce(@sql,'') + 'update ' + tblname + ' set status = ''' + [status] + ''' where ' + field + ' = ' + ident + ';')
    	from @values_for_update
    	
    	if @debug = 1 print @sql
    
    	exec (@sql)
    end
    go
    --Eingabeparameter @values_for_update
    declare @values_for_update type1
    insert into @values_for_update values
    ('t1','col12','11','00'),
    ('t2','col22','22','00')
    --rufft die SP auf
    exec [dbo].[setStatus] @values_for_update=@values_for_update,@debug=1
    go
    --zeigt aktualisierte Daten an
    select * from t1
    select * from t2
    go
    --löscht alle Testobjekte
    drop table t1, t2;
    drop proc [dbo].[setStatus];
    drop type type1;
    go
    

    Gruß Yury
    Samstag, 25. Dezember 2010 15:20
  • Wow, danke.

    ich sehe dass ich bisher keine Ahnung hatte von Stored Procedures.

    Gruß Andreas

    Samstag, 25. Dezember 2010 16:10
  • Hallo Andreas,

    weisen die Tabellen dieselbe Struktur auf, kann man partitionierte Sichten einsetzen.

    use tempdb
    go
    
    --Testtabellen
    create table t1(col1 int primary key check (col1 between 1 and 1000),
    			[status] tinyint,
    			col3 nvarchar(10))
    create table t2(col1 int primary key check (col1 between 1001 and 2000),
    			[status] tinyint,
    			col3 nvarchar(10))
    go
    
    --Testdaten
    insert into t1 values(123,11,'11')
    insert into t2 values(1234,11,'22')
    go
    
    --Partitionierte Sicht
    create view v12 as
    	select col1, [status], col3 from t1
    	union all
    	select col1, [status], col3 from t2
    go
    
    --update (kann auch in eine SP eingepackt werden)
    update v12 set col3 = '33' where [status] = 11
    go
    
    --zeigt alle Daten an
    select * from t1
    union all
    select * from t2
    go
    
    --löscht alle Testobjekte
    drop table t1, t2;
    drop view v12;
    
    --Hier ist das Resultset:
    --col1	status	col3
    ---------------------
    --123	11	33
    --1234	11	33
    
    

    Gruß Yury
    Dienstag, 28. Dezember 2010 17:52
  • Hallo Andreas,
    nicht alles was machbar ist, ist auch wirklich gut. Der zweite Ansatz von Yury ist wahrscheinlich der bessere, wobei ich die Zugriffe auf verschiedene Tabellen durch entsprechende Prozeduren trennen würde um optimale Performance, Übersichtlichkeit und Berechtigungsvergaben hinzubekommen.

    Ergänzend dazu empfehle ich noch folgenden Artikel:
    http://www.insidesql.org/blogs/frankkalis/2004/07/16/dynamisches-sql-fluch-und-segen

    Einen schönen Tag noch,
    Christoph


    Microsoft SQL Server MVP
    http://www.insidesql.org/blogs/cmu

    Montag, 3. Januar 2011 07:21