Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

Cara melewatkan array ke prosedur tersimpan SQL Server

SQL Server 2008 (atau lebih baru)

Pertama, di database Anda, buat dua objek berikut:

CREATE TYPE dbo.IDList
AS TABLE
(
  ID INT
);
GO

CREATE PROCEDURE dbo.DoSomethingWithEmployees
  @List AS dbo.IDList READONLY
AS
BEGIN
  SET NOCOUNT ON;

  SELECT ID FROM @List; 
END
GO

Sekarang dalam kode C# Anda:

// Obtain your list of ids to send, this is just an example call to a helper utility function
int[] employeeIds = GetEmployeeIds();

DataTable tvp = new DataTable();
tvp.Columns.Add(new DataColumn("ID", typeof(int)));

// populate DataTable from your List here
foreach(var id in employeeIds)
    tvp.Rows.Add(id);

using (conn)
{
    SqlCommand cmd = new SqlCommand("dbo.DoSomethingWithEmployees", conn);
    cmd.CommandType = CommandType.StoredProcedure;
    SqlParameter tvparam = cmd.Parameters.AddWithValue("@List", tvp);
    // these next lines are important to map the C# DataTable object to the correct SQL User Defined Type
    tvparam.SqlDbType = SqlDbType.Structured;
    tvparam.TypeName = "dbo.IDList";
    // execute query, consume results, etc. here
}

SQL Server 2005

Jika Anda menggunakan SQL Server 2005, saya masih akan merekomendasikan fungsi split melalui XML. Pertama, buat fungsi:

CREATE FUNCTION dbo.SplitInts
(
   @List      VARCHAR(MAX),
   @Delimiter VARCHAR(255)
)
RETURNS TABLE
AS
  RETURN ( SELECT Item = CONVERT(INT, Item) FROM
      ( SELECT Item = x.i.value('(./text())[1]', 'varchar(max)')
        FROM ( SELECT [XML] = CONVERT(XML, '<i>'
        + REPLACE(@List, @Delimiter, '</i><i>') + '</i>').query('.')
          ) AS a CROSS APPLY [XML].nodes('i') AS x(i) ) AS y
      WHERE Item IS NOT NULL
  );
GO

Sekarang prosedur tersimpan Anda dapat menjadi:

CREATE PROCEDURE dbo.DoSomethingWithEmployees
  @List VARCHAR(MAX)
AS
BEGIN
  SET NOCOUNT ON;

  SELECT EmployeeID = Item FROM dbo.SplitInts(@List, ','); 
END
GO

Dan dalam kode C# Anda, Anda hanya perlu meneruskan daftar sebagai '1,2,3,12' ...

Saya menemukan metode melewati parameter bernilai tabel menyederhanakan pemeliharaan solusi yang menggunakannya dan sering meningkatkan kinerja dibandingkan dengan implementasi lain termasuk XML dan pemisahan string.

Input didefinisikan dengan jelas (tidak ada yang harus menebak apakah pembatas adalah koma atau titik koma) dan kami tidak memiliki ketergantungan pada fungsi pemrosesan lain yang tidak jelas tanpa memeriksa kode untuk prosedur tersimpan.

Dibandingkan dengan solusi yang melibatkan skema XML yang ditentukan pengguna alih-alih UDT, ini melibatkan sejumlah langkah yang serupa tetapi menurut pengalaman saya kode yang jauh lebih sederhana untuk dikelola, dipelihara, dan dibaca.

Dalam banyak solusi, Anda mungkin hanya memerlukan satu atau beberapa UDT ini (Jenis yang Ditentukan Pengguna) yang Anda gunakan kembali untuk banyak prosedur tersimpan. Seperti contoh ini, persyaratan umum adalah melewati daftar pointer ID, nama fungsi menjelaskan konteks apa yang harus diwakili oleh Id tersebut, nama tipe harus generik.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Perbedaan Antara sys.objects, sys.system_objects, dan sys.all_objects di SQL Server

  2. Melewati varchar yang penuh dengan nilai yang dibatasi koma ke fungsi SQL Server IN

  3. Grup concat di SQL Server

  4. Apakah Kunci Asing meningkatkan kinerja kueri?

  5. Gunakan DB_ID() untuk Mengembalikan ID Database di SQL Server