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

Haruskah parameter bernilai tabel digunakan di sini?

Ya, gunakan parameter bernilai tabel. Pertama buat tipe:

CREATE TYPE dbo.StudentIDs(ID INT PRIMARY KEY);

Sekarang prosedur Anda dapat menggunakan ini (perhatikan bahwa saya telah mengubah IN . bersarang Anda kueri untuk bergabung dengan benar):

CREATE PROCEDURE dbo.MarkStudentsAsDeleted
  @IDs dbo.StudentIDs READONLY
AS
BEGIN
  SET NOCOUNT ON;

  UPDATE s SET IsDeleted = 1
    FROM dbo.Students AS s
    INNER JOIN dbo.Class AS c
    ON s.StudentId = c.StudentId
    INNER JOIN dbo.ClassValueTable AS ct
    ON c.PassId = ct.Id
    WHERE ct.IsDeleted <> 1
    AND EXISTS (SELECT 1 FROM @IDs WHERE StudentID = s.StudentID);
END 
GO

Dan kode C# Anda akan melewati DataTable atau bagaimanapun Anda telah mengumpulkan koleksi activeIds, bukan daftar yang dipisahkan koma.

DataTable dt = new DataTable();
dt.Columns.Add("ID", typeof(int));
dt.Rows.Add(1);
dt.Rows.Add(2);
dt.Rows.Add(3);
dt.Rows.Add(4);

... open connection etc. ...

SqlCommand cmd = new SqlCommand("dbo.MarkStudentsAsDeleted", conn);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter tvp1 = cmd.Parameters.AddWithValue("@IDs", dt);
tvp1.SqlDbType = SqlDbType.Structured;
cmd.ExecuteNonQuery();

... close, dispose, etc. ...

Jika Anda ingin memaksakan meneruskan string ke prosedur tersimpan, Anda harus menggunakan fungsi split. Misalnya:

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

Sekarang prosedur tersimpan Anda dapat menjadi:

CREATE PROCEDURE dbo.MarkStudentsAsDeleted
  @IDs VARCHAR(MAX)
AS
BEGIN
  SET NOCOUNT ON;

  UPDATE s SET IsDeleted = 1
    FROM dbo.Students AS s
    INNER JOIN dbo.Class AS c
    ON s.StudentId = c.StudentId
    INNER JOIN dbo.ClassValueTable AS ct
    ON c.PassId = ct.Id
    WHERE ct.IsDeleted <> 1
    AND EXISTS (SELECT 1 FROM dbo.SplitInts(@IDs, ',') WHERE Item = s.StudentID);
END 
GO



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Buat array JSON bersarang menggunakan FOR JSON PATH

  2. Konversi tipe data varchar ke tipe data datetime menghasilkan kesalahan nilai di luar rentang

  3. SQL INSERT INTO dari beberapa tabel

  4. Permintaan SQL untuk memilih tanggal di antara dua tanggal

  5. Bagaimana cara melihat koneksi SQL Server yang aktif?