88 messaggi dal 19 ottobre 2012
Ciao a tutti,
qualcuno mi sa dire se si può ad un parametro di una SP passare più di un valore? non trovo nulla sui vari forum che soddisfino la mia esigenza
Ringrazio anticipatamente
Un saluto

Giorgio
88 messaggi dal 19 ottobre 2012
Ciao,
sono riuscito a risolvere e posto la funzione che mi è servita per il mio scopo:

CREATE function [dbo].[delimited_string_to_table] (
@delimiter char(1)
, @string text
)
returns @table table (
seqnbr int not null
, string varchar(255) not null
)
as
begin

declare @pos int
declare @textpos int
declare @chunklen smallint
declare @tmpstr varchar(8000)
declare @leftover varchar(8000)
declare @tmpval varchar(8000)
declare @seq int = 1

set @textpos = 1
set @leftover = ''

while @textpos <= datalength(@string)
begin

set @chunklen = 8000 - datalength(@leftover) / 2
set @tmpstr = @leftover + substring(@string, @textpos, @chunklen)
set @textpos = @textpos + @chunklen

set @pos = charindex(@delimiter, @tmpstr)

while @pos > 0
begin
set @tmpval = ltrim(rtrim(left(@tmpstr, @pos - 1)))
insert @table (seqnbr, string) values(@seq, @tmpval)
set @tmpstr = substring(@tmpstr, @pos + 1, len(@tmpstr))
set @pos = charindex(@delimiter, @tmpstr)
set @seq = @seq + 1
end

set @leftover = @tmpstr

end

if len(rtrim(ltrim(@leftover))) != 0
insert @table(seqnbr, string) values (@seq, ltrim(rtrim(@leftover)))

return

end
GO


Successivamente ho inserito nella mia Stored Procedure la join alla funzione:

JOIN dbo.delimited_string_to_table(',', @ChiaveCliente)

e poi eseguo la SP:

exec @CheckInsoluti '1,2,3,4,5'

e mi restituisce le rige di questi clienti

Un saluto

Giorgio
1.976 messaggi dal 27 luglio 2005
Contributi
salve Giorgio,
la soluzione e' perfetta... ma... :D
personalmente non mi e' mai piaciuto utilizzare il tipo di dato text, e non mi e' mai piaciuto utilizzare i "cicli di loop" all'interno di un sistema orientato ai set di dati...
personalmente, quindi, avrei implementato la funzionalita' di split in altro modo, cioe' usando una common table expression ricorsiva, tra l'altro piu' efficiente...
tra l'altro, a partire da SQL Server 2016, e' presente anche un'apposita fuzione di sistema, STRING_SPLIT https://docs.microsoft.com/it-it/sql/t-sql/functions/string-split-transact-sql?view=sql-server-ver15, che puo' fare la stessa cosa...

tornando al codice secco, la mia soluzione sarebbe probabilmente simile a
SET NOCOUNT ON;
USE tempdb;
GO
IF OBJECT_ID('[dbo].[ufn_Split2Table]') <> 0
  DROP FUNCTION [dbo].[ufn_Split2Table]
GO
SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[ufn_Split2Table] (
  @delimiter char(1),
  @string varchar(MAX)
  )
  RETURNS @tbl TABLE (
    seqnbr int IDENTITY(1, 1) NOT NULL,                      
    string varchar(255) NOT NULL
  ) 
  AS  BEGIN

  /* splitta il parametro in base al separatore @delimiter */
  

  SET @string = LTRIM(RTRIM(@string));

  IF (LEN(@string) > 0) BEGIN
    WITH Pieces(pn, startPos, endPos, List) AS (
      SELECT 1, CAST(1 AS bigint), CHARINDEX(@delimiter, @string), @string AS List
      UNION ALL
      SELECT pn + 1, endPos + 1, CHARINDEX(@delimiter, Pieces.List , endPos + 1), Pieces.List
      FROM Pieces  
      WHERE endPos > 0
      ),
    cte AS (
      SELECT LTRIM(RTRIM(SUBSTRING(Pieces.List, startPos, CASE WHEN endPos > 0 THEN endPos-startPos ELSE 2147483647 END))) AS [string]
          FROM Pieces
      )
      INSERT @tbl ( [string] )
        SELECT cte.[string]
          FROM cte
          WHERE LEN(cte.[string]) > 0;
    END;

  RETURN;

END;
GO
PRINT 'Test';
SELECT *
  FROM [dbo].[ufn_Split2Table] (',', ',1,12,123,1234,,,    999,');
GO
CREATE TABLE [dbo].[Tb1] (
  Id int NOT NULL PRIMARY KEY,
  Valore varchar(10)
  );

INSERT INTO [dbo].[Tb1]
  VALUES ( 1, 'giorgio' ), ( 2, 'flaviovb' ), ( 3, 'andrea' ), ( 4, 'daniele' );
GO
PRINT 'esempio utilizzo: il parametro NON contiene Id = 3 e contiene Id = 99 che non e'' presente in tabella';
SELECT t.[Id], t.[Valore]
  FROM [dbo].[Tb1] t
    JOIN [dbo].[ufn_Split2Table] ( ',', '1,2,4, 9') u ON u.[string] = CONVERT(varchar(255), t.[Id]);
GO
DROP FUNCTION [dbo].[ufn_Split2Table];
DROP TABLE [dbo].[Tb1];
--<---------------------
Test
seqnbr      string
----------- -----------
1           1
2           12
3           123
4           1234
5           999

esempio utilizzo: il parametro NON contiene Id = 3 e contiene Id = 99 che non e' presente in tabella
Id          Valore
----------- ----------
1           giorgio
2           flaviovb
4           daniele


non ho ben compreso se in effetti [seqnbr] ti serva o meno, e se lo split deve ritornare un int o un varchar(255) come nel tuo esempio...

salutoni romagnoli e buon weekend...
--
Andrea

Andrea Montanari
http://www.hotelsole.com - http://www.hotelsole.com/asql/index.php
88 messaggi dal 19 ottobre 2012
Buongiorno Andrea e grazie dei preziosi consigli. SI lo split deve restituire valori varchar.
Sapevo della stringa string?split ma la fortuna mi porta ad implementare questo su SQL 2012.
Sicuramente provo la tua soluzione che sar' sicuramente pi\ ottimale.
Auguro anche a te una buona domenica

Giorgio

Torna al forum | Feed RSS

ASPItalia.com non è responsabile per il contenuto dei messaggi presenti su questo servizio, non avendo nessun controllo sui messaggi postati nei propri forum, che rappresentano l'espressione del pensiero degli autori.