Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Passaggio array a SP... magari...

67 views
Skip to first unread message

Mago Merlino

unread,
Jul 14, 2003, 4:55:22 AM7/14/03
to
Devo creare una SP per abilitare un utente ad una serie di distretti.
Ho le seguenti tabelle:

Utente
CODUtente VARCHAR(7)
DESUtente

Distretto
CODDistretto VARCHAR(6)
DESDistretto

ProfiloUtente
CODUtente
CODDistretto

La mia SP dovrà inserire un record in ProfiloUtente per ogni distretto da
abilitare.
Quale è secondo voi il miglio modo per passare alla SP il CODUtente e tutta
la serie di distretti da abilitare?
Ho pensato ad una stringa con tutti i distretti separati da virgola... ma
non sono molto sicuro.

Grazie.


Lorenzo Benaglia

unread,
Jul 14, 2003, 4:58:33 AM7/14/03
to
Mago Merlino wrote:
> Quale è secondo voi il miglio modo per passare alla SP il CODUtente e
> tutta la serie di distretti da abilitare?

Ciao,

Nella versione attuale di SQL Server non è possibile definire vettori (come
quelli presenti in altri linguaggi di programmazione).

Per una soluzione alternativa alla classica query dinamica, prova a leggere
quella proposta dal SQL Server MVP Fernando G. Guerrero.

"Passing Multivalued Variables to a Stored Procedure"

I have a table called Stores that contains information about the grocery
stores in the chain I work for. I need to write a stored procedure that
accepts a list of store IDs as an argument and returns details about those
stores. If I know the list of store IDs ahead of time—for example 210 and
213—I can use the following query:

SELECT *
FROM Stores
WHERE storeid IN(210,213)

However, when I don't know the IDs, I can create the @storeids VARCHAR(1000)
input parameter for my stored procedure and change the WHERE clause as
follows:

WHERE storeid IN(@storeids)

If I pass one store ID, as the following sample EXEC statement shows:

EXEC GetStores @storeids = '210'

the new WHERE clause works. But if I pass the multiple store IDs that the
following EXEC statement shows:

EXEC GetStores @storeids = '210, 213'

the query returns no records. I can use dynamic execution to solve the
problem by constructing my entire T-SQL statement in a variable such as
@strsql, then using EXEC (@strsql) to execute it. However, I'd rather not
implement this solution because the user executing the stored procedure must
have direct permissions for the statement executed dynamically and not just
EXECUTE permissions on the stored procedure. How can I pass variables that
contain multiple values to my stored procedure without using dynamic
execution?

If you prefer not to construct the query dynamically and execute it, you can
use string-manipulation functions in a static query to return the result you
want. I learned the trick I'm going to use in the solution from SQL Server
MVP Fernando G. Guerrero. The following query, which uses the Authors table
in the Pubs sample database, shows how to pass multivalued variables:

USE pubs
DECLARE @lnames AS varchar(1000)
SET @lnames = 'White,Greene,Carson'
SELECT * FROM Authors
WHERE CHARINDEX(',' + au_lname + ',', ',' + @lnames + ',') > 0

This successful query doesn't require dynamic execution. Here's how the
query works. The CHARINDEX() function looks for the au_lname column wrapped
with commas inside the @lnames variable wrapped with commas. The reason for
wrapping both the au_lname column and the @lnames variable with commas is to
avoid an incorrect match when you're looking for a value that's also a
substring of another value. For example, suppose you're looking for the name
'White,Greene,Carson'. An author in the Authors table has the last name
Greene, and another author has the last name Green. By looking for ',' +
au_lname + ',' in ',' + @lnames + ',' you ensure that the query doesn't
return Green. Note that if the @lnames variable contains spaces—for example,
'White, Greene, Carson'—you must remove them because the CHARINDEX()
function treats a space as any other character, and when looking for
',Greene,' in ',White, Greene, Carson,', the query won't find a match. You
can use the REPLACE() function to replace all spaces in the variable with
empty strings, as the following query shows:

USE pubs
DECLARE @lnames AS varchar(1000)
SET @lnames = 'White, Greene, Carson'
SELECT * FROM Authors
WHERE CHARINDEX(',' + au_lname + ',', ',' +
REPLACE(@lnames, ' ', '') + ',') > 0

Note, however, that if performance is important, you're better off using
dynamic execution, which lets you use an index on au_lname. The solution
that uses static T-SQL requires a table scan.

> Grazie.
Prego.

Ciao!

--
Lorenzo Benaglia
Microsoft MVP - SQL Server

Mago Merlino

unread,
Jul 14, 2003, 7:07:14 AM7/14/03
to
> Per una soluzione alternativa alla classica query dinamica, prova a
leggere
> quella proposta dal SQL Server MVP Fernando G. Guerrero.

L'avevo detto che occorreva una bella stringa? :-)
Ma a questo punto, fissato l'utilizzo della stringa per passare i parametri,
il mio problema è un altro.
All'interno della SP dovrei fare una INSERT per ogni valore contenuto nella
stringa dei paramentri.
E' come se dovessi fare un ciclo FETCH sulla stringa... :-o
Come potrei realizzare la cosa? Esiste per caso una funziona tipo split?
Grazie.


Andrea Montanari

unread,
Jul 14, 2003, 8:06:34 AM7/14/03
to
salve,
"Mago Merlino" <magomer...@Mfreehtml.it> ha scritto nel messaggio
news:C9wQa.5176$B8....@news.edisontel.com...
l'MVP Erland Sommarskog ha recentemente pubblicato un bellissimo articolo
sugli array e liste, liberamente consultabile presso
http://www.algonet.se/~sommar/arrays-in-sql.html
che predeve anche una specie si split con una funzione che ritorna una
tabella con una riga per ogni valore presente nell'array...
ci sono anche altre informazioni che sono molto interessanti riguradanti
operazioni su questi soggetti...
e... si... dovresti iterare l'array per effettuare gli insert, a meno che la
tabella termporanea che andreai a costruire non riesca a contenere tutte le
informazioni da te desiderate e previste...

saluti
Andrea Montanari
montanar...@virgilio.it
http://www.asql.biz/DbaMgr.shtm
DbaMgr2k ver 0.4.0 - DbaMgr ver 0.50.0
(my vb6+sql-dmo little try to provide MS MSDE 1.0 and MSDE 2000 a visual
interface)
--------- remove DMO to reply


AlessandroD

unread,
Jul 14, 2003, 8:11:20 AM7/14/03
to

"Mago Merlino" <magomer...@Mfreehtml.it> ha scritto nel messaggio
news:_duQa.5119$B8....@news.edisontel.com...
Io utilizzo spesso delle tabelle di lavoro per simulare dei vettori, nel tuo
caso una cosa così:

ZT_DistrettiPerUtente
----------------------
CODUtente
CODDistretto

Da client riempio la tabella, nella SP accedo ai dati contenuti nella
tabella e mi regolo di conseguenza.
Ciao, Alessandro

0 new messages