Cách đơn giản để chuyển đổi các cột và hàng trong SQL?


110

Làm cách nào để chuyển đổi cột với hàng trong SQL? Có lệnh đơn giản nào để chuyển vị không?

tức là biến kết quả này:

        Paul  | John  | Tim  |  Eric
Red     1       5       1       3
Green   8       4       3       5
Blue    2       2       9       1

vào cái này:

        Red  | Green | Blue
Paul    1       8       2
John    5       4       2
Tim     1       3       9
Eric    3       5       1

PIVOT có vẻ quá phức tạp cho kịch bản này.


1
stackoverflow.com/questions/10699997/… là một câu hỏi tương tự.
Tim Dearborn

Câu trả lời:


145

Có một số cách mà bạn có thể chuyển đổi dữ liệu này. Trong bài đăng ban đầu của mình, bạn đã nói rằng điều đó PIVOTcó vẻ quá phức tạp đối với tình huống này, nhưng nó có thể được áp dụng rất dễ dàng bằng cách sử dụng cả hàm UNPIVOTPIVOT trong SQL Server.

Tuy nhiên, nếu bạn không có quyền truy cập vào các hàm đó, điều này có thể được sao chép bằng cách sử dụng UNION ALLtới UNPIVOTvà sau đó là một hàm tổng hợp với CASEcâu lệnh PIVOT:

Tạo bảng:

CREATE TABLE yourTable([color] varchar(5), [Paul] int, [John] int, [Tim] int, [Eric] int);

INSERT INTO yourTable
    ([color], [Paul], [John], [Tim], [Eric])
VALUES
    ('Red', 1, 5, 1, 3),
    ('Green', 8, 4, 3, 5),
    ('Blue', 2, 2, 9, 1);

Kết hợp Tất cả, Tổng hợp và Phiên bản CASE:

select name,
  sum(case when color = 'Red' then value else 0 end) Red,
  sum(case when color = 'Green' then value else 0 end) Green,
  sum(case when color = 'Blue' then value else 0 end) Blue
from
(
  select color, Paul value, 'Paul' name
  from yourTable
  union all
  select color, John value, 'John' name
  from yourTable
  union all
  select color, Tim value, 'Tim' name
  from yourTable
  union all
  select color, Eric value, 'Eric' name
  from yourTable
) src
group by name

Xem SQL Fiddle với Demo

Thực UNION ALLhiện UNPIVOTdữ liệu bằng cách chuyển các cột Paul, John, Tim, Ericthành các hàng riêng biệt. Sau đó, bạn áp dụng hàm tổng hợp sum()với casecâu lệnh để lấy các cột mới cho mỗi color.

Unpivot và Pivot phiên bản tĩnh:

Cả hàm UNPIVOTPIVOThàm trong máy chủ SQL đều làm cho việc chuyển đổi này trở nên dễ dàng hơn nhiều. Nếu bạn biết tất cả các giá trị mà bạn muốn chuyển đổi, bạn có thể mã hóa chúng thành một phiên bản tĩnh để nhận được kết quả:

select name, [Red], [Green], [Blue]
from
(
  select color, name, value
  from yourtable
  unpivot
  (
    value for name in (Paul, John, Tim, Eric)
  ) unpiv
) src
pivot
(
  sum(value)
  for color in ([Red], [Green], [Blue])
) piv

Xem SQL Fiddle với Demo

Truy vấn bên trong với hàm UNPIVOTthực hiện chức năng tương tự như UNION ALL. Nó lấy danh sách các cột và biến nó thành các hàng, PIVOTsau đó thực hiện chuyển đổi cuối cùng thành các cột.

Phiên bản Pivot động:

Nếu bạn có một số lượng cột không xác định ( Paul, John, Tim, Erictrong ví dụ của bạn) và sau đó một số lượng màu không xác định để chuyển đổi, bạn có thể sử dụng sql động để tạo danh sách UNPIVOTvà sau đó PIVOT:

DECLARE @colsUnpivot AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX),
    @colsPivot as  NVARCHAR(MAX)

select @colsUnpivot = stuff((select ','+quotename(C.name)
         from sys.columns as C
         where C.object_id = object_id('yourtable') and
               C.name <> 'color'
         for xml path('')), 1, 1, '')

select @colsPivot = STUFF((SELECT  ',' 
                      + quotename(color)
                    from yourtable t
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')


set @query 
  = 'select name, '+@colsPivot+'
      from
      (
        select color, name, value
        from yourtable
        unpivot
        (
          value for name in ('+@colsUnpivot+')
        ) unpiv
      ) src
      pivot
      (
        sum(value)
        for color in ('+@colsPivot+')
      ) piv'

exec(@query)

Xem SQL Fiddle với Demo

Phiên bản động truy vấn cả hai yourtablevà sau đó truy vấn sys.columnsbảng để tạo danh sách các mục đến UNPIVOTPIVOT. Điều này sau đó được thêm vào một chuỗi truy vấn để được thực thi. Điểm cộng của phiên bản động là nếu bạn có danh sách thay đổi colorsvà / hoặc namesdanh sách này sẽ tạo danh sách tại thời điểm chạy.

Cả ba truy vấn sẽ tạo ra cùng một kết quả:

| NAME | RED | GREEN | BLUE |
-----------------------------
| Eric |   3 |     5 |    1 |
| John |   5 |     4 |    2 |
| Paul |   1 |     8 |    2 |
|  Tim |   1 |     3 |    9 |

Tôi nên nhấn mạnh rằng tôi muốn có một phương pháp để chuyển đổi kết quả của một truy vấn trên cơ sở dữ liệu. Một lệnh loại chuyển vị đơn giản có thể được thực thi trên tập kết quả từ một truy vấn mà không cần phải biết bất cứ điều gì về chính truy vấn hoặc các cột, bảng, v.v. mà nó đang trích xuất thông tin. Một cái gì đó như: (TRANSPOSE (SELECT ......)) Trong ví dụ của tôi đưa ra ở trên, hãy tưởng tượng rằng bảng đầu tiên là một tập kết quả được tạo từ một truy vấn rất phức tạp liên quan đến nhiều bảng, liên hợp, trục, v.v. Tuy nhiên, kết quả là bảng đơn giản. Tôi chỉ muốn lật các cột có hàng trong kết quả này.
edezzie 14/11/12

Tôi đang chuyển kết quả cho ac # DataTable. Tôi có thể xây dựng một phương thức đơn giản 'Transpose (Datatable dt)' để thực hiện việc đó ở đó, nhưng có gì trong SQL để thực hiện việc này không.
edezzie 14/11/12

@edezzie không có một cách đơn giản nào trong SQL để làm điều này. Bạn có thể có thể thay đổi phiên bản động để chuyển vào tên bảng và lấy thông tin từ các bảng hệ thống.
Taryn

Có lý do gì khiến bạn không đánh dấu câu trả lời tuyệt vời này là TRẢ LỜI? Hãy tặng @bluefeet một huy chương!
Fandango68,

Điều này đang hoạt động tốt, hãy chọn * từ Bỏ chia bảng (giá trị cho tên trong ([Paul], [John], [Tim], [Eric])) lên trục xoay (tối đa (giá trị) cho màu trong ([Đỏ], [Xanh]) , [Blue])) p nhưng có thể viết lựa chọn này * từ Bảng bỏ chia không (giá trị cho tên trong ([Paul], [John], [Tim], [Eric])) lên tổng hợp (max (giá trị) cho màu trong (CHỌN MÀU TỪ TABLENAME)) p thay vì nhập giá trị được trích dẫn không thể truy xuất các giá trị trực tiếp bằng cách sử dụng truy vấn chọn.
Mogli

20

Điều này thường yêu cầu bạn phải biết trước TẤT CẢ các nhãn cột VÀ hàng. Như bạn có thể thấy trong truy vấn bên dưới, tất cả các nhãn được liệt kê hoàn toàn trong cả thao tác UNPIVOT và (lại) PIVOT.

Thiết lập lược đồ MS SQL Server 2012 :

create table tbl (
    color varchar(10), Paul int, John int, Tim int, Eric int);
insert tbl select 
    'Red' ,1 ,5 ,1 ,3 union all select
    'Green' ,8 ,4 ,3 ,5 union all select
    'Blue' ,2 ,2 ,9 ,1;

Truy vấn 1 :

select *
from tbl
unpivot (value for name in ([Paul],[John],[Tim],[Eric])) up
pivot (max(value) for color in ([Red],[Green],[Blue])) p

Kết quả :

| NAME | RED | GREEN | BLUE |
-----------------------------
| Eric |   3 |     5 |    1 |
| John |   5 |     4 |    2 |
| Paul |   1 |     8 |    2 |
|  Tim |   1 |     3 |    9 |

Ghi chú bổ sung:

  1. Với một tên bảng, bạn có thể xác định tất cả các tên cột từ sys.columns hoặc thủ thuật FOR XML bằng cách sử dụng local-name () .
  2. Bạn cũng có thể tạo danh sách các màu riêng biệt (hoặc giá trị cho một cột) bằng FOR XML.
  3. Ở trên có thể được kết hợp thành một lô sql động để xử lý bất kỳ bảng nào.

11

Tôi muốn chỉ ra một số giải pháp khác để chuyển đổi các cột và hàng trong SQL.

Cách đầu tiên là - sử dụng CURSOR. Mặc dù sự đồng thuận chung trong cộng đồng chuyên nghiệp là tránh xa Con trỏ máy chủ SQL, nhưng vẫn có những trường hợp nên sử dụng con trỏ. Dù sao, Con trỏ trình bày cho chúng ta một tùy chọn khác để chuyển các hàng thành cột.

  • Mở rộng theo chiều dọc

    Tương tự như PIVOT, con trỏ có khả năng động để nối thêm hàng khi tập dữ liệu của bạn mở rộng để bao gồm nhiều số chính sách hơn.

  • Mở rộng theo chiều ngang

    Không giống như PIVOT, con trỏ vượt trội trong lĩnh vực này vì nó có thể mở rộng để bao gồm tài liệu mới được thêm vào mà không làm thay đổi tập lệnh.

  • Phân tích hiệu suất

    Hạn chế chính của việc chuyển các hàng thành cột bằng CURSOR là một nhược điểm được liên kết với việc sử dụng con trỏ nói chung - chúng có chi phí hiệu suất đáng kể. Điều này là do Con trỏ tạo ra một truy vấn riêng biệt cho mỗi thao tác FETCH NEXT.

Một giải pháp khác để chuyển các hàng thành cột là sử dụng XML.

Giải pháp XML để chuyển các hàng thành cột về cơ bản là một phiên bản tối ưu của PIVOT trong đó nó giải quyết giới hạn cột động.

Phiên bản XML của tập lệnh giải quyết hạn chế này bằng cách sử dụng kết hợp Đường dẫn XML, T-SQL động và một số hàm tích hợp (tức là STUFF, QUOTENAME).

  • Mở rộng theo chiều dọc

    Tương tự như PIVOT và Con trỏ, các chính sách mới được thêm vào có thể được truy xuất trong phiên bản XML của tập lệnh mà không làm thay đổi tập lệnh gốc.

  • Mở rộng theo chiều ngang

    Không giống như PIVOT, các tài liệu mới được thêm vào có thể được hiển thị mà không làm thay đổi tập lệnh.

  • Phân tích hiệu suất

    Về mặt IO, thống kê của phiên bản XML của tập lệnh gần như tương tự với PIVOT - điểm khác biệt duy nhất là XML có lần quét bảng dtTranspose lần thứ hai nhưng lần này là từ bộ đệm dữ liệu đọc logic.

Bạn có thể tìm thêm một số giải pháp về các giải pháp này (bao gồm một số bản đồ T-SQL thực tế) trong bài viết này: https://www.sqlshack.com/multiple-options-to-transposing-rows-into-columns/


8

Dựa trên giải pháp này từ bluefeet, đây là một thủ tục được lưu trữ sử dụng sql động để tạo bảng chuyển vị. Nó yêu cầu tất cả các trường là số ngoại trừ cột đã hoán vị (cột sẽ là tiêu đề trong bảng kết quả):

/****** Object:  StoredProcedure [dbo].[SQLTranspose]    Script Date: 11/10/2015 7:08:02 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:      Paco Zarate
-- Create date: 2015-11-10
-- Description: SQLTranspose dynamically changes a table to show rows as headers. It needs that all the values are numeric except for the field using for     transposing.
-- Parameters: @TableName - Table to transpose
--             @FieldNameTranspose - Column that will be the new headers
-- Usage: exec SQLTranspose <table>, <FieldToTranspose>
-- =============================================
ALTER PROCEDURE [dbo].[SQLTranspose] 
  -- Add the parameters for the stored procedure here
  @TableName NVarchar(MAX) = '', 
  @FieldNameTranspose NVarchar(MAX) = ''
AS
BEGIN
  -- SET NOCOUNT ON added to prevent extra result sets from
  -- interfering with SELECT statements.
  SET NOCOUNT ON;

  DECLARE @colsUnpivot AS NVARCHAR(MAX),
  @query  AS NVARCHAR(MAX),
  @queryPivot  AS NVARCHAR(MAX),
  @colsPivot as  NVARCHAR(MAX),
  @columnToPivot as NVARCHAR(MAX),
  @tableToPivot as NVARCHAR(MAX), 
  @colsResult as xml

  select @tableToPivot = @TableName;
  select @columnToPivot = @FieldNameTranspose


  select @colsUnpivot = stuff((select ','+quotename(C.name)
       from sys.columns as C
       where C.object_id = object_id(@tableToPivot) and
             C.name <> @columnToPivot 
       for xml path('')), 1, 1, '')

  set @queryPivot = 'SELECT @colsResult = (SELECT  '','' 
                    + quotename('+@columnToPivot+')
                  from '+@tableToPivot+' t
                  where '+@columnToPivot+' <> ''''
          FOR XML PATH(''''), TYPE)'

  exec sp_executesql @queryPivot, N'@colsResult xml out', @colsResult out

  select @colsPivot = STUFF(@colsResult.value('.', 'NVARCHAR(MAX)'),1,1,'')

  set @query 
    = 'select name, rowid, '+@colsPivot+'
        from
        (
          select '+@columnToPivot+' , name, value, ROW_NUMBER() over (partition by '+@columnToPivot+' order by '+@columnToPivot+') as rowid
          from '+@tableToPivot+'
          unpivot
          (
            value for name in ('+@colsUnpivot+')
          ) unpiv
        ) src
        pivot
        (
          sum(value)
          for '+@columnToPivot+' in ('+@colsPivot+')
        ) piv
        order by rowid'
  exec(@query)
END

Bạn có thể kiểm tra nó bằng bảng được cung cấp với lệnh này:

exec SQLTranspose 'yourTable', 'color'

argg. nhưng tôi muốn một nơi mà tất cả các lĩnh vực là nvarchar (max)
Hamish

1
Đối với tất cả các lĩnh vực nvarchar (max) chỉ cần thay đổi số tiền (giá trị) với tối đa (giá trị) trong dòng thứ 6 từ cuối cùng
Paco Zarate

2

Tôi làm UnPivotđầu tiên và lưu trữ các kết quả trong CTEvà sử dụng CTEtrong Pivotphẫu thuật.

Bản giới thiệu

with cte as
(
select 'Paul' as Name, color, Paul as Value 
 from yourTable
 union all
 select 'John' as Name, color, John as Value 
 from yourTable
 union all
 select 'Tim' as Name, color, Tim as Value 
 from yourTable
 union all
 select 'Eric' as Name, color, Eric as Value 
 from yourTable
 )

select Name, [Red], [Green], [Blue]
from
(
select *
from cte
) as src
pivot 
(
  max(Value)
  for color IN ([Red], [Green], [Blue])
) as Dtpivot;

2

Thêm vào câu trả lời tuyệt vời của @Paco Zarate ở trên, nếu bạn muốn chuyển một bảng có nhiều loại cột, thì hãy thêm cột này vào cuối dòng 39, vì vậy nó chỉ chuyển đổi intcác cột:

and C.system_type_id = 56   --56 = type int

Đây là toàn bộ truy vấn đang được thay đổi:

select @colsUnpivot = stuff((select ','+quotename(C.name)
from sys.columns as C
where C.object_id = object_id(@tableToPivot) and
      C.name <> @columnToPivot and C.system_type_id = 56    --56 = type int
for xml path('')), 1, 1, '')

Để tìm những cái khác system_type_id, hãy chạy cái này:

select name, system_type_id from sys.types order by name

1

Tôi muốn chia sẻ mã mà tôi đang sử dụng để chuyển một đoạn văn bản được phân tách dựa trên + câu trả lời bluefeet. Trong chương trình này, tôi được triển khai như một thủ tục trong MS SQL 2005

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:      ELD.
-- Create date: May, 5 2016.
-- Description: Transpose from rows to columns the user split function.
-- =============================================
CREATE PROCEDURE TransposeSplit @InputToSplit VARCHAR(8000)
    ,@Delimeter VARCHAR(8000) = ','
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @colsUnpivot AS NVARCHAR(MAX)
        ,@query AS NVARCHAR(MAX)
        ,@queryPivot AS NVARCHAR(MAX)
        ,@colsPivot AS NVARCHAR(MAX)
        ,@columnToPivot AS NVARCHAR(MAX)
        ,@tableToPivot AS NVARCHAR(MAX)
        ,@colsResult AS XML

    SELECT @tableToPivot = '#tempSplitedTable'

    SELECT @columnToPivot = 'col_number'

    CREATE TABLE #tempSplitedTable (
        col_number INT
        ,col_value VARCHAR(8000)
        )

    INSERT INTO #tempSplitedTable (
        col_number
        ,col_value
        )
    SELECT ROW_NUMBER() OVER (
            ORDER BY (
                    SELECT 100
                    )
            ) AS RowNumber
        ,item
    FROM [DB].[ESCHEME].[fnSplit](@InputToSplit, @Delimeter)

    SELECT @colsUnpivot = STUFF((
                SELECT ',' + quotename(C.NAME)
                FROM [tempdb].sys.columns AS C
                WHERE C.object_id = object_id('tempdb..' + @tableToPivot)
                    AND C.NAME <> @columnToPivot
                FOR XML path('')
                ), 1, 1, '')

    SET @queryPivot = 'SELECT @colsResult = (SELECT  '','' 
                    + quotename(' + @columnToPivot + ')
                  from ' + @tableToPivot + ' t
                  where ' + @columnToPivot + ' <> ''''
          FOR XML PATH(''''), TYPE)'

    EXEC sp_executesql @queryPivot
        ,N'@colsResult xml out'
        ,@colsResult OUT

    SELECT @colsPivot = STUFF(@colsResult.value('.', 'NVARCHAR(MAX)'), 1, 1, '')

    SET @query = 'select name, rowid, ' + @colsPivot + '
        from
        (
          select ' + @columnToPivot + ' , name, value, ROW_NUMBER() over (partition by ' + @columnToPivot + ' order by ' + @columnToPivot + ') as rowid
          from ' + @tableToPivot + '
          unpivot
          (
            value for name in (' + @colsUnpivot + ')
          ) unpiv
        ) src
        pivot
        (
          MAX(value)
          for ' + @columnToPivot + ' in (' + @colsPivot + ')
        ) piv
        order by rowid'

    EXEC (@query)

    DROP TABLE #tempSplitedTable
END
GO

Tôi đang trộn giải pháp này với thông tin về cách sắp xếp các hàng không theo thứ tự theo ( SQLAuthority.com ) và chức năng tách trên MSDN ( social.msdn.microsoft.com )

Khi bạn thực hiện sản phẩm

DECLARE @RC int
DECLARE @InputToSplit varchar(MAX)
DECLARE @Delimeter varchar(1)

set @InputToSplit = 'hello|beautiful|world'
set @Delimeter = '|'

EXECUTE @RC = [TransposeSplit] 
   @InputToSplit
  ,@Delimeter
GO

bạn nhận được kết quả tiếp theo

  name       rowid  1      2          3
  col_value  1      hello  beautiful  world

1

Bằng cách này, Chuyển đổi tất cả Dữ liệu Từ Trường (Cột) Trong Bảng sang Bản ghi (Hàng).

Declare @TableName  [nvarchar](128)
Declare @ExecStr    nvarchar(max)
Declare @Where      nvarchar(max)
Set @TableName = 'myTableName'
--Enter Filtering If Exists
Set @Where = ''

--Set @ExecStr = N'Select * From '+quotename(@TableName)+@Where
--Exec(@ExecStr)

Drop Table If Exists #tmp_Col2Row

Create Table #tmp_Col2Row
(Field_Name nvarchar(128) Not Null
,Field_Value nvarchar(max) Null
)

Set @ExecStr = N' Insert Into #tmp_Col2Row (Field_Name , Field_Value) '
Select @ExecStr += (Select N'Select '''+C.name+''' ,Convert(nvarchar(max),'+quotename(C.name) + ') From ' + quotename(@TableName)+@Where+Char(10)+' Union All '
         from sys.columns as C
         where (C.object_id = object_id(@TableName)) 
         for xml path(''))
Select @ExecStr = Left(@ExecStr,Len(@ExecStr)-Len(' Union All '))
--Print @ExecStr
Exec (@ExecStr)

Select * From #tmp_Col2Row
Go

0

Tôi đã có thể sử dụng giải pháp của Paco Zarate và nó hoạt động rất tốt. Tôi đã phải thêm một dòng ("SET ANSI_WARNINGS ON"), nhưng đó có thể là một cái gì đó độc đáo đối với cách tôi sử dụng hoặc gọi nó. Có một vấn đề với việc sử dụng của tôi và tôi hy vọng ai đó có thể giúp tôi với nó:

Giải pháp chỉ hoạt động với một bảng SQL thực tế. Tôi đã thử nó với một bảng tạm thời và một bảng trong bộ nhớ (được khai báo) nhưng nó không hoạt động với những bảng đó. Vì vậy, trong mã gọi của tôi, tôi tạo một bảng trên cơ sở dữ liệu SQL của mình và sau đó gọi SQLTranspose. Một lần nữa, nó hoạt động tuyệt vời. Nó chỉ là những gì tôi muốn. Đây là vấn đề của tôi:

Để giải pháp tổng thể thực sự năng động, tôi cần tạo bảng đó nơi tôi tạm thời lưu trữ thông tin đã chuẩn bị sẵn mà tôi đang gửi tới SQLTranspose "nhanh", và sau đó xóa bảng đó khi SQLTranspose được gọi. Việc xóa bảng có vấn đề với kế hoạch triển khai cuối cùng của tôi. Mã cần chạy từ ứng dụng người dùng cuối (một nút trên biểu mẫu / menu Microsoft Access). Khi tôi sử dụng quy trình SQL này (tạo bảng SQL, gọi SQLTranspose, xóa bảng SQL), ứng dụng người dùng cuối gặp lỗi vì tài khoản SQL được sử dụng không có quyền xóa bảng.

Vì vậy, tôi nghĩ có một số giải pháp khả thi:

  1. Tìm cách làm cho SQLTranspose hoạt động với một bảng tạm thời hoặc một biến bảng đã khai báo.

  2. Tìm ra một phương pháp khác để chuyển đổi các hàng và cột không yêu cầu bảng SQL thực tế.

  3. Tìm ra một phương pháp thích hợp để cho phép tài khoản SQL được người dùng cuối của tôi sử dụng để thả một bảng. Đó là một tài khoản SQL được chia sẻ duy nhất được mã hóa vào ứng dụng Access của tôi. Có vẻ như quyền là đặc quyền kiểu dbo không thể được cấp.

Tôi nhận ra rằng một số điều này có thể đảm bảo một chủ đề và câu hỏi khác, riêng biệt. Tuy nhiên, vì có khả năng một giải pháp có thể chỉ là một cách khác để thực hiện việc chuyển đổi các hàng và cột, tôi sẽ thực hiện bài đăng đầu tiên của mình ở đây trong chủ đề này.

CHỈNH SỬA: Tôi cũng đã thay thế sum (giá trị) bằng max (giá trị) ở dòng thứ 6 từ cuối, như Paco đã đề xuất.

BIÊN TẬP:

Tôi đã tìm ra một cái gì đó phù hợp với tôi. Tôi không biết nó có phải là tốt nhất không câu trả lời hay không.

Tôi có một tài khoản người dùng chỉ đọc được sử dụng để thực thi các quy trình liên tục và do đó tạo báo cáo đầu ra từ cơ sở dữ liệu. Vì hàm SQLTranspose tôi đã tạo sẽ chỉ hoạt động với bảng "hợp pháp" (không phải bảng được khai báo và không phải bảng tạm thời) nên tôi phải tìm ra cách để tài khoản người dùng chỉ đọc có thể tạo (và sau đó xóa) bảng .

Tôi lý luận rằng vì mục đích của mình, tài khoản người dùng được phép tạo bảng là điều ổn. Người dùng vẫn không thể xóa bảng. Giải pháp của tôi là tạo một lược đồ trong đó tài khoản người dùng được ủy quyền. Sau đó, bất cứ khi nào tôi tạo, sử dụng hoặc xóa bảng đó, hãy giới thiệu nó với lược đồ được chỉ định.

Lần đầu tiên tôi phát hành lệnh này từ tài khoản 'sa' hoặc 'sysadmin': CREATE SCHEMA ro AUTHORIZATION

Khi bất kỳ lúc nào tôi tham chiếu đến bảng "tmpoutput", tôi chỉ định nó như ví dụ sau:

thả bảng ro.tmpoutput


Tôi đã tìm ra một cái gì đó phù hợp với tôi. Tôi không biết đó có phải là câu trả lời tốt nhất hay không.
CraigD
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.