cyklus for v sql   otázka

SQL, Databáze

Dobrý den,

potřebovala bych poradit. Mám vytvořenou web site ve Visual Studiu 2008 a v jedné ze stránek potřebuji na základě uživatelem zadaných údajů vybrat data z databáze.

Databázi mám v sql serveru 2008, ve které mám vytvořenou proceduru sp.Vystup, která mi zminovaná data vybírá. Nyní mám procedura 4 parametry. potřebovala bych ale, aby byl pocet parametru menitelny v rozsahu 4 až 8, podle toho kolik jich uzivatel pomoci CheckBoxu vybere.

Myslela jsem, že upravim proceduru tak, aby mela 8parametru a při spuštění potřebuju nejaky prikaz,výraz nebo cyklus,ktery mi overi jestli parametr 1,2,3,4,5,...8 byl zadán nebo ne.

Prosím, poraďte mi.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

A nevyřešil by se problém použitím nepovinných parametrů? Ty se definují tak, že k normálnímu parametru zadáte defaultní hodnotu.

Např:

@parametr1 VARCHAR(255)=NULL output --nepovinný výstupní parametr
@parametr2 VARCHAR(255)=NULL --nepovinný vstupní parametr

Pokud je nadeklarujete takto, aplikace která proceduru volá může tyto parametry vynechat. Tzn. pokud budou první 4 parametry zadány vždy, nadeklarujte je normálně (ty budou povinné) a další 4 zadejte takto a pak už bude jedno jestli aplikace posílá 4,5,6,7 nebo 8 parametrů.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

To můj problém zřejmě nevyřeší. myslela jsem spíše na cyklus for. Jenže nevím jakou mám syntaxi v sql jazyce.

Myslela jsem, že by to mohlo být nějak následovně

for (i=1,i=8,i++)
if exists parametr[i]
{
     telo procedury
     next i
}
else 
{
     next i
}
nahlásit spamnahlásit spam 0 odpovědětodpovědět

Pokud máte na mysli T-SQL na MS SQL serveru tak tam se cyklus udělat dá. Ale na co potřebujete cyklus? Stačí otestovat zda je parametrem něco zasláno. Jak to tedy máte vyřešeno? Parametrem z aplikace vždy něco příjde (pokud máte všechny parametry nastavené jako povinné tak musí...)

Budu tedy uvažovat že parametrem příjde hodnota 0 (aplikace nic neposlala nebo příjde jiné číslo)

Můžete to testovat takto:

IF @parametr1=0
BEGIN
   --zde bude kód který se má provést při parametru 0
END

ELSE

BEGIN
   --zde bude kód který se provede když přjde cokoliv jiného než 0
END

Jinak pokud máte ve webové aplikace checkboxy tak bych to udělal tak, že bych pro každý checkbox vytvořil parametr typu BIT a nastavoval bych mu TRUE nebo FALSE podle toho zda checkbox je/není zaškrtnutý. Tím pádem Vám dotazem vždy příde stejný počet parametrů a vy budete testovat pouze jejich hodnotu 1 nebo 0.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Dobrý den, s tím testováním parametrů to vypadá dobře. To určitě takhle bude fungovat. Děkuji za pomoc. Na straně serveru to chápu, avšak ještě mi není jasné jak vytvořit ty parametry checkboxů. Jsem úplný amatér. Tak jestli mi ještě poradíte, budu ráda, ušetříte mi spoustu času hledání.

Nyní mám ještě jeden problém. Ta procedura kterou mám vytvořenou vybírá z učité tabulky data, podle zadanych parametru. Mezi parametry také patří RokOd a RokDo. Když teda cykly v sql jazyce nejdou, tak jak mám teda udělat to, že chci aby procedura vybrala data podle zadanych parametru pro rok=RokOd, pak vybrala data pro rok=RokOd+1, atd. až po rok=RokDo.???? tohle bych řešila právě jednoduchým cyklem for,ale v sql nemám vůbec nuteší jak na to.

Budu ráda za každý nápad.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Dobrý den, pokud používáte MS SQL server tak tam ve stored procedurách cykly dělat jdou, ale pro tento případ bych řekl že to je zbytečné.

Takže popořadě.

Parametry z VB na databázi načtete třeba takto:

    Sub nacistData()

        Dim connectionString As String = "SERVER=nazev_serveru;DATABASE=jmeno_database;UID=prihlasovaci_jmeno;PWD=heslo" 'spojení s DB
        Dim sqlConnect As New SqlClient.SqlConnection(connectionString)

        Dim dtData As DataTable = New DataTable
        Dim adapterSeznam As SqlClient.SqlDataAdapter = New SqlClient.SqlDataAdapter
        Dim sqlDotaz As SqlClient.SqlCommand = New SqlClient.SqlCommand

        Dim parametr1 As Boolean = Me.checkbox1.value
        Dim parametr2 As Boolean = Me.checkbox2.value


        With sqlDotaz
            .Connection = sqlConnect
            .CommandType = CommandType.StoredProcedure
            .CommandText = "jmeno_stored_procedury"

            .Parameters.Add("parametr1", SqlDbType.Bit).Direction() = ParameterDirection.Input
            .Parameters("parametr1").Value = parametr1

            .Parameters.Add("parametr2", SqlDbType.Bit).Direction() = ParameterDirection.Input
            .Parameters("parametr2").Value = parametr2
        End With


        adapterSeznam.SelectCommand = sqlDotaz

        Try
            adapterSeznam.Fill(dtData)
        Catch ex As Exception
            MsgBox("Došlo k chybě") 'zde by bylo dobré neodchytávat obecnou vyjímku ale pohrát si s tím a odchytávat nějaké konkrétní
        Finally
            sqlConnect.Close()
        End Try


    End Sub

To co je v dataTable dtData tak to je výsledek co se Vám načetlo z databáze.

Jinak moc nechápu tu druhou část dotazu. Pokud potřebujete vybrat něco v určitém rozmezí dat tak na co cykl? To stačí dát do podmínky. Tak do té procedury přidáte ještě parametry datumOd a datumDo typu dateTime a pak je dáte do podmínky:

Select * FROM mojeTabulke WHERE datum>=@datumOd AND datum<=@datumDo

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Tu první část rozhodně vyzkouším. K té druhé části jde o to.

Mám formulář kde uživatel vybere rokod, rokdo, ukazatel a libovolny pocet registrovanych uzivatelu (max. však 5) se kterými se chce porovnat.

Kvůli tomu, že počet uživatelů se kterými se chce srovnat je měnitelný jsem řešila tu první část.

Zkusím trošku vysvětlit tu proceduru:

Mám proceduru, kde:

1) vybírám podle kritérií data a vkládám je do tab_vystupek.

2) Potom z tab_vystupek vybírám data pouze pro Uzivatele1 a tyto data přiřadím do tab_vystup1. Pokud data pro pro uzivatele1 v tab_vystupek neexistují tak jim přiřadím hodnotu 0.

3) tohle opakuju pro zbylé uživatele

4) je to zbytečně složité, ale zaprvé jsem amatér a za druhé z těch dat potom vytvářím pohled, který potřebuju mít v tomto formátu:

rok skola1 skola2 skola3 .....

rokod hodnota hodnota hodnota ......

rokod+1 hodnota hodnota hodnota .....

.

.

.

rokdo hodnota hodnota hodnota ......

Buď tabulka obsahuje konkrétní hodnotu nebo 0. Potřebuju data přesně v tomhle formátu, jelikož je pak používám v grafech. kde x osa jsou roky a na y ose jsou hodnoty a jednotlivé školy jsou série grafu.

Zde mám kód mé procedury: právě že zatím v ní není měnitelný počet škol ani žádná podmínka pro počet let. Je to zatím natvrdo pro 3 školy a 3roky. Právě bych to chtěla nějak zautomatizovat at můžu hýbat s počtem těch škol a nějak vyřešit ty roky...jsem z toho úplně na větvi. Nejsem žádný zkušený programátor. :( Ale snažím se co můžu.

USE [BenchmarkingDatabase]
GO
/****** Object:  StoredProcedure [dbo].[spVystup]    Script Date: 04/25/2010 13:13:45 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[spVystup] 
@ID_RokOd int,
@ID_RokDo int,
@ID_Skola1 int,
@ID_Skola2 int,
@ID_Skola3 int,
@ID_Ukazatel int
AS
BEGIN

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Tab_Vystupek]') AND type in (N'U'))
DROP TABLE [dbo].[Tab_Vystupek]

CREATE TABLE [dbo].[Tab_Vystupek](
	[ID] [int] NOT NULL,
	[ID_Rok] [int] NOT NULL,
	[ID_Skola] [int] NOT NULL,
	[ID_Ukazatel] [int] NULL,
	[ID_Vypocet_ID_Ukazatel] [int] NOT NULL,
	[Hodnota] [decimal](18, 0) NOT NULL
) ON [PRIMARY]

INSERT INTO dbo.Tab_Vystupek 
SELECT * FROM dbo.Tab_Vystup 
WHERE (ID_Rok >= @ID_RokOd AND ID_Rok<=@ID_RokDo) And (ID_Skola=@ID_Skola1 or ID_Skola=@ID_Skola2 or ID_Skola=@ID_Skola3) and ID_Vypocet_ID_Ukazatel=@ID_Ukazatel 


IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Tab_Vystup1]') AND type in (N'U'))
DROP TABLE [dbo].[Tab_Vystup1]

CREATE TABLE [dbo].[Tab_Vystup1](

	[ID] [int] IDENTITY(1,1) NOT NULL,
	[ID_Rok] [int] NOT NULL,
	[ID_Skola1] [int] NOT NULL,
	[Hodnota] [decimal](18, 0) NOT NULL
	CONSTRAINT [PK_Tab_Vystup1] 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]
BEGIN

IF(EXISTS(SELECT Hodnota, ID_Skola, ID_Rok FROM dbo.Tab_Vystupek WHERE ID_Skola=@ID_Skola1 And ID_Rok=@ID_RokOD) )
	BEGIN
	INSERT INTO dbo.Tab_Vystup1 
	SELECT ID_Rok, ID_Skola, Hodnota FROM dbo.Tab_Vystupek 
	WHERE ID_Skola=@ID_Skola1 and ID_Rok=@ID_RokOd
	END
ElSE
	BEGIN
	insert dbo.Tab_Vystup1 values (@ID_RokOd,@ID_Skola1,0)
	END
END

IF(EXISTS(SELECT Hodnota, ID_Skola, ID_Rok FROM dbo.Tab_Vystupek WHERE ID_Skola=@ID_Skola1 And ID_Rok=@ID_RokOD+1) )
	BEGIN
	INSERT INTO dbo.Tab_Vystup1 
	SELECT ID_Rok, ID_Skola, Hodnota FROM dbo.Tab_Vystupek 
	WHERE ID_Skola=@ID_Skola1 and ID_Rok=@ID_RokOd+1
	END
ElSE
	BEGIN
	insert dbo.Tab_Vystup1 values (@ID_RokOd+1,@ID_Skola1,0)
	END
END

IF(EXISTS(SELECT Hodnota, ID_Skola, ID_Rok FROM dbo.Tab_Vystupek WHERE ID_Skola=@ID_Skola1 And ID_Rok=@ID_RokDo) )
	BEGIN
	INSERT INTO dbo.Tab_Vystup1 
	SELECT ID_Rok, ID_Skola, Hodnota FROM dbo.Tab_Vystupek 
	WHERE ID_Skola=@ID_Skola1 and ID_Rok=@ID_RokDo
	END
ElSE
	BEGIN
	insert dbo.Tab_Vystup1 values (@ID_RokDo,@ID_Skola1,0)
	END

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Tab_Vystup2]') AND type in (N'U'))
DROP TABLE [dbo].[Tab_Vystup2]

CREATE TABLE [dbo].[Tab_Vystup2](

	[ID] [int] IDENTITY(1,1) NOT NULL,
	[ID_Rok] [int] NOT NULL,
	[ID_Skola2] [int] NOT NULL,
	[Hodnota] [decimal](18, 0) NOT NULL
	CONSTRAINT [PK_Tab_Vystup2] 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]
BEGIN

IF(EXISTS(SELECT Hodnota, ID_Skola, ID_Rok FROM dbo.Tab_Vystupek WHERE ID_Skola=@ID_Skola2 And ID_Rok=@ID_RokOD) )
	BEGIN
	INSERT INTO dbo.Tab_Vystup2 
	SELECT ID_Rok, ID_Skola, Hodnota FROM dbo.Tab_Vystupek 
	WHERE ID_Skola=@ID_Skola2 and ID_Rok=@ID_RokOd
	END
ElSE
	BEGIN
	insert dbo.Tab_Vystup2 values (@ID_RokOd,@ID_Skola2,0)
	END
END

IF(EXISTS(SELECT Hodnota, ID_Skola, ID_Rok FROM dbo.Tab_Vystupek WHERE ID_Skola=@ID_Skola2 And ID_Rok=@ID_RokOD+1) )
	BEGIN
	INSERT INTO dbo.Tab_Vystup2 
	SELECT ID_Rok, ID_Skola, Hodnota FROM dbo.Tab_Vystupek 
	WHERE ID_Skola=@ID_Skola2 and ID_Rok=@ID_RokOd+1 
	END
ElSE
	BEGIN
	insert dbo.Tab_Vystup2 values (@ID_RokOd+1,@ID_Skola2,0)
	END
	
IF(EXISTS(SELECT Hodnota, ID_Skola, ID_Rok FROM dbo.Tab_Vystupek WHERE ID_Skola=@ID_Skola2 And ID_Rok=@ID_RokDo))
	BEGIN
	INSERT INTO dbo.Tab_Vystup2 
	SELECT ID_Rok, ID_Skola, Hodnota FROM dbo.Tab_Vystupek 
	WHERE ID_Skola=@ID_Skola2 and ID_Rok=@ID_RokDo
	END
ElSE
	BEGIN
	insert dbo.Tab_Vystup2 values (@ID_RokDo,@ID_Skola2,0)
	END

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Tab_Vystup3]') AND type in (N'U'))
DROP TABLE [dbo].[Tab_Vystup3]

CREATE TABLE [dbo].[Tab_Vystup3](

	[ID] [int] IDENTITY(1,1) NOT NULL,
	[ID_Rok] [int] NOT NULL,
	[ID_Skola3] [int] NOT NULL,
	[Hodnota] [decimal](18, 0) NOT NULL
	CONSTRAINT [PK_Tab_Vystup3] 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]
BEGIN

IF(EXISTS(SELECT Hodnota, ID_Skola, ID_Rok FROM dbo.Tab_Vystupek WHERE ID_Skola=@ID_Skola3 And ID_Rok=@ID_RokOD) )
	BEGIN
	INSERT INTO dbo.Tab_Vystup3 
	SELECT ID_Rok, ID_Skola, Hodnota FROM dbo.Tab_Vystupek 
	WHERE ID_Skola=@ID_Skola3 and ID_Rok=@ID_RokOd
	END
ElSE
	BEGIN
	insert dbo.Tab_Vystup3 values (@ID_RokOd,@ID_Skola3,0)
	END

IF(EXISTS(SELECT Hodnota, ID_Skola, ID_Rok FROM dbo.Tab_Vystupek WHERE ID_Skola=@ID_Skola3 And ID_Rok=@ID_RokOD+1) )
	BEGIN
	INSERT INTO dbo.Tab_Vystup3 
	SELECT ID_Rok, ID_Skola, Hodnota FROM dbo.Tab_Vystupek 
	WHERE ID_Skola=@ID_Skola3 and ID_Rok=@ID_RokOd+1
	END
ElSE
	BEGIN
	insert dbo.Tab_Vystup3 values (@ID_RokOd+1,@ID_Skola3,0)
	END


IF(EXISTS(SELECT Hodnota, ID_Skola, ID_Rok FROM dbo.Tab_Vystupek WHERE ID_Skola=@ID_Skola3 And ID_Rok=@ID_RokDo) )
	BEGIN
	INSERT INTO dbo.Tab_Vystup3 
	SELECT ID_Rok, ID_Skola, Hodnota FROM dbo.Tab_Vystupek 
	WHERE ID_Skola=@ID_Skola3 and ID_Rok=@ID_RokDo
	END
ElSE
	BEGIN
	insert dbo.Tab_Vystup3 values (@ID_RokDo,@ID_Skola3,0)
	END
end

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Zkuste uvést, co konkrétního má SP dělat. Častým problémem návrhu databáze je stejný přístup jako k běžnému programování, které je však zde zcela odlišné.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Cyklus se dá provést pomocí Cursoru.

Jinak nepovinné parametry by se také daly použít pomocí xml, které se do procedury pošle. Na malý projekt s osmi parametry je to ale zbytečné a složité.

Každopádně se přikláním se k názoru, že konkrétní problém by byl určitě lepší.

nahlásit spamnahlásit spam 0 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.
  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:
Heslo:

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback