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

Bagaimana saya bisa mengganti semua bidang kunci dalam string dengan nilai pengganti dari tabel di T-SQL?

Ada beberapa cara yang bisa dilakukan. Saya akan daftar dua cara. Masing-masing memiliki kelebihan dan kekurangan. Saya pribadi akan menggunakan yang pertama (Dynamic SQL).

1. SQL Dinamis

  • Kelebihan:Cepat, tidak memerlukan rekursi
  • Kekurangan:Tidak dapat digunakan untuk memperbarui variabel tabel

2. CTE rekursif

  • Keuntungan:Memungkinkan pembaruan variabel tabel
  • Kekurangan:Memerlukan rekursi dan memori intensif, CTE rekursif lambat

1.A. SQL Dinamis:Tabel reguler dan tabel Sementara.

Contoh ini menggunakan tabel sementara sebagai sumber teks:

CREATE TABLE #tt_text(templatebody VARCHAR(MAX));
INSERT INTO #tt_text(templatebody)VALUES
    ('This is to inform #first_name# about the issues regarding #location#');

CREATE TABLE #tt_repl(variable VARCHAR(256),template_value VARCHAR(8000));
INSERT INTO #tt_repl(variable,template_value)VALUES
    ('#first_name#','Joseph William'),
    ('#location#','Alaska');

DECLARE @rep_call NVARCHAR(MAX)='templatebody';
SELECT
    @rep_call='REPLACE('[email protected]_call+','''+REPLACE(variable,'''','''''')+''','''+REPLACE(template_value,'''','''''')+''')'
FROM
    #tt_repl;

DECLARE @stmt NVARCHAR(MAX)='SELECT '[email protected]_call+' FROM #tt_text';
EXEC sp_executesql @stmt;

/* Use these statements if you want to UPDATE the source rather than SELECT from it
DECLARE @stmt NVARCHAR(MAX)='UPDATE #tt_text SET templatebody='[email protected]_call;
EXEC sp_executesql @stmt;
SELECT * FROM #tt_text;*/

DROP TABLE #tt_repl;
DROP TABLE #tt_text;

1.B. SQL Dinamis:Variabel tabel.

Membutuhkan tabel yang didefinisikan sebagai tipe tabel tertentu. Contoh definisi tipe:

CREATE TYPE dbo.TEXT_TABLE AS TABLE(
    id INT IDENTITY(1,1) PRIMARY KEY,
    templatebody VARCHAR(MAX)
);
GO

Tentukan variabel tabel jenis ini, dan gunakan dalam pernyataan SQL Dinamis sebagai berikut. Perhatikan bahwa memperbarui variabel tabel dengan cara ini tidak mungkin.

DECLARE @tt_text dbo.TEXT_TABLE;
INSERT INTO @tt_text(templatebody)VALUES
    ('This is to inform #first_name# about the issues regarding #location#');

DECLARE @tt_repl TABLE(id INT IDENTITY(1,1),variable VARCHAR(256),template_value VARCHAR(8000));
INSERT INTO @tt_repl(variable,template_value)VALUES
    ('#first_name#','Joseph William'),
    ('#location#','Alaska');

DECLARE @rep_call NVARCHAR(MAX)='templatebody';
SELECT
    @rep_call='REPLACE('[email protected]_call+','''+REPLACE(variable,'''','''''')+''','''+REPLACE(template_value,'''','''''')+''')'
FROM
    @tt_repl;

DECLARE @stmt NVARCHAR(MAX)='SELECT '[email protected]_call+' FROM @tt_text';
EXEC sp_executesql @stmt,N'@tt_text TEXT_TABLE READONLY',@tt_text;

2. CTE rekursif:

Satu-satunya alasan mengapa Anda menulis ini menggunakan CTE rekursif adalah karena Anda bermaksud memperbarui variabel tabel, atau Anda tidak diizinkan untuk menggunakan SQL Dinamis entah bagaimana (misalnya kebijakan perusahaan?).

Perhatikan bahwa level rekursi maksimum default adalah 100. Jika Anda memiliki lebih dari 100 variabel pengganti, Anda harus meningkatkan level ini dengan menambahkan OPTION(MAXRECURSION 32767) di akhir kueri (lihat Petunjuk Kueri - MAXRECURSION ).

DECLARE @tt_text TABLE(id INT IDENTITY(1,1),templatebody VARCHAR(MAX));
INSERT INTO @tt_text(templatebody)VALUES
    ('This is to inform #first_name# about the issues regarding #location#');

DECLARE @tt_repl TABLE(id INT IDENTITY(1,1),variable VARCHAR(256),template_value VARCHAR(8000));
INSERT INTO @tt_repl(variable,template_value)VALUES
    ('#first_name#','Joseph William'),
    ('#location#','Alaska');

;WITH cte AS (
    SELECT
        t.id,
        l=1,
        templatebody=REPLACE(t.templatebody,r.variable,r.template_value)
    FROM
        @tt_text AS t
        INNER JOIN @tt_repl AS r ON r.id=1
    UNION ALL
    SELECT
        t.id,
        l=l+1,
        templatebody=REPLACE(t.templatebody,r.variable,r.template_value)
    FROM
        cte AS t
        INNER JOIN @tt_repl AS r ON r.id=t.l+1
)
UPDATE
    @tt_text
SET
    templatebody=cte.templatebody
FROM
    @tt_text AS t
    INNER JOIN cte ON 
        cte.id=t.id
WHERE
    cte.l=(SELECT MAX(id) FROM @tt_repl);

/* -- if instead you wanted to select the replaced strings, comment out 
   -- the above UPDATE statement, and uncomment this SELECT statement:
SELECT 
    templatebody 
FROM 
    cte 
WHERE 
    l=(SELECT MAX(id) FROM @tt_repl);*/

SELECT*FROM @tt_text;


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cara Membuat Batasan Pemeriksaan pada Beberapa Kolom di SQL Server - Tutorial SQL Server / TSQL Bagian 84

  2. Apakah ada cara untuk membedakan atau mengelompokkan dengan teks (atau ntext) di SQL Server 2005?

  3. Bagaimana mencegah pembaruan ke tabel, dengan pengecualian untuk satu situasi

  4. Apakah ada hit kinerja yang parah untuk menggunakan Kunci Asing di SQL Server?

  5. Dalam SQL, bagaimana Anda bisa mengelompokkan dalam rentang?