টেবিলগুলি * টেবিল-মূল্যবান প্যারামিটার (টিভিপি) হিসাবে ব্যবহার করা হচ্ছে


18

এমএস এসকিউএল ২০০৮ টিভিপি সমর্থন করে: প্রসেসিংয়ের জন্য সঞ্চিত কার্যক্রমে ডেটা আপলোড করার জন্য একটি দরকারী বৈশিষ্ট্য।

কোনও ব্যবহারকারী-সংজ্ঞায়িত প্রকার তৈরির পরিবর্তে, বিদ্যমান টেবিল সংজ্ঞাটি উত্তোলন করা কি সম্ভব? উদাহরণস্বরূপ, নিম্নলিখিত স্বাক্ষর সহ কোনও সঞ্চিত ক্রিয়াকলাপ তৈরি করা সম্ভব?

CREATE PROCEDURE usp_InsertProductionLocation
@TVP **LocationTable** READONLY

ডকুমেন্টেশন মনে হয় যে এটি সম্ভব নয়।

কোডের উদাহরণ

/*
Sample code from:
http://msdn.microsoft.com/en-us/library/bb510489.aspx
*/

USE AdventureWorks2008R2;
GO

/* Create a table type. */
CREATE TYPE LocationTableType AS TABLE 
( LocationName VARCHAR(50)
, CostRate INT );
GO

/* Create a procedure to receive data for the table-valued parameter. */
CREATE PROCEDURE usp_InsertProductionLocation
    @TVP LocationTableType READONLY
    AS 
    SET NOCOUNT ON
    INSERT INTO [AdventureWorks2008R2].[Production].[Location]
           ([Name]
           ,[CostRate]
           ,[Availability]
           ,[ModifiedDate])
        SELECT *, 0, GETDATE()
        FROM  @TVP;
        GO

/* Declare a variable that references the type. */
DECLARE @LocationTVP 
AS LocationTableType;

/* Add data to the table variable. */
INSERT INTO @LocationTVP (LocationName, CostRate)
    SELECT [Name], 0.00
    FROM 
    [AdventureWorks2008R2].[Person].[StateProvince];

/* Pass the table variable data to a stored procedure. */
EXEC usp_InsertProductionLocation @LocationTVP;
GO

/*
The following is not part of the original source code:
*/

CREATE TABLE LocationTable(
 LocationName VARCHAR(50)
, CostRate INT );
GO

উত্তর:


16

না, আপনি একটি বিদ্যমান সারণী সংজ্ঞাটি উত্তোলন করতে পারবেন না, আপনাকে একটি স্পষ্ট প্রকারের সংজ্ঞা দিতে হবে। এটি 2007 সালে ফিরে জিজ্ঞাসা করা হয়েছিল এবং "ঠিক করা হবে না" হিসাবে বন্ধ করা হয়েছিল তবে আমি আপনাকে দৃ up়ভাবে ভোট দেওয়ার জন্য উত্সাহিত করি এবং আপনার ব্যবহারের ক্ষেত্রে বর্ণিত একটি মন্তব্য এবং এটি কীভাবে আপনার ব্যবসাকে আরও উত্পাদনশীল হতে সহায়তা করবে তা বলার জন্য উত্সাহিত করি। আপনি এটিকে চেষ্টা করতে এবং স্বয়ংক্রিয়ভাবে চালানো কতটা ক্লান্তিকর হতে পারে তা প্রদর্শনের জন্যও এই প্রশ্নটির দিকে ইঙ্গিত করতে পারেন।

ইউজারওয়য়েসে আইটেম (পূর্বে সংযুক্ত # 294130)

আপনি আজ এটি গতিশীলভাবে করতে পারেন, যদিও ... উদাহরণস্বরূপ আপনার সাধারণ সংজ্ঞা:

-- you would pass these two in as parameters of course:
DECLARE
  @TableName SYSNAME = N'LocationTable',
  @TypeName  SYSNAME = N'LocationTypeTable';

DECLARE @sql NVARCHAR(MAX) = N'';

SELECT @sql = @sql + N',' + CHAR(13) + CHAR(10) + CHAR(9) 
    + QUOTENAME(c.name) + ' '
    + s.name + CASE WHEN LOWER(s.name) LIKE '%char' THEN 
        '(' + CONVERT(VARCHAR(12), (c.max_length/
        (CASE LOWER(LEFT(s.name, 1)) WHEN N'n' THEN 2 ELSE 1 END))) + ')' 
        ELSE '' END
        -- need much more conditionals here for other data types
    FROM sys.columns AS c
    INNER JOIN sys.types AS s
    ON c.system_type_id = s.system_type_id
    AND c.user_type_id = s.user_type_id
    WHERE c.[object_id] = OBJECT_ID(@TableName);

SELECT @sql = N'CREATE TYPE ' + @TypeName
    + ' AS TABLE ' + CHAR(13) + CHAR(10) + '(' + STUFF(@sql, 1, 1, '')
    + CHAR(13) + CHAR(10) + ');';

PRINT @sql;
-- EXEC sp_executesql @sql;

ফলাফল:

CREATE TYPE LocationTypeTable AS TABLE 
(
    [LocationName] varchar(50),
    [CostRate] int
);

দাবি অস্বীকার: এটি MAX ধরণের অন্যান্য ধরণের, সংখ্যার জন্য যথার্থতা এবং স্কেল ইত্যাদির সাথে কাজ করে না The চূড়ান্ত সমাধানটি সমস্ত সম্ভাব্য কলাম সংজ্ঞা বিবেচনার জন্য আরও দৃust় হতে হবে তবে এটি আপনাকে একটি সূচনা দেওয়া উচিত।

এসকিউএল সার্ভার ২০১২-তে নতুন নতুন ডিএমভি এবং সঞ্চিত প্রক্রিয়া রয়েছে যা সিস্টেটিপস এবং সিসের বিপরীতে সমস্ত শর্তযুক্ত লজিকের সাথে ঝামেলা ছাড়াই বিদ্যমান সারণীগুলি (বা সঞ্চিত পদ্ধতি বা অ্যাড-হক প্রশ্নগুলি) থেকে কলাম মেটাডেটা অর্জন করা আরও সহজ করে তুলবে। কলাম. আমি ডিসেম্বর মাসে এই উন্নতিগুলি সম্পর্কে সংক্ষেপে ব্লগ করেছি । এটি এখনও ক্লান্তিকর, তবে এটি উপরের কোথাও ভয়াবহ অনাকাঙ্ক্ষিত স্প্যাগেটি এবং কেবল "[টেবিল x] এর অনুলিপি হিসাবে" বলার ক্ষমতা ...


4

বিদ্যমান সারণীতে থাকতে পারে একই স্কিমার সাথে একটি টাইপ তৈরি করতে নিম্নলিখিত সঞ্চিত পদ্ধতি তৈরি করে আমি এই সমস্যাটি মোকাবিলা করেছি।

Create PROCEDURE [dbo].[Sp_DefineTypeOutOfTableSchema]
@TableNames NVARCHAR(500)
AS
BEGIN

DECLARE @TableName NVARCHAR(100)
DECLARE @strSQL NVARCHAR(max)
DECLARE @strSQLCol NVARCHAR(1000)
DECLARE @ColName NVARCHAR(100)
DECLARE @ColDataTaype NVARCHAR(50)
DECLARE @ColDefault NVARCHAR(50)
DECLARE @ColIsNulable NVARCHAR(50)
DECLARE @ColCharMaxlen NVARCHAR(50)
DECLARE @ColNumPrec NVARCHAR(50)
DECLARE @ColNumScal NVARCHAR(50)


IF LEN(@TableNames) > 0 SET @TableNames = @TableNames + ',' 

WHILE LEN(@TableNames) > 0 
    BEGIN

        SELECT @TableName = LTRIM(SUBSTRING(@TableNames, 1, CHARINDEX(',', @TableNames) - 1))

        DECLARE schemaCur CURSOR FOR 
        SELECT COLUMN_NAME,DATA_TYPE,IS_NULLABLE,COLUMN_DEFAULT,CHARACTER_MAXIMUM_LENGTH,NUMERIC_PRECISION,NUMERIC_SCALE  FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME =@TableName

        OPEN schemaCur

        SELECT @strSQL=''

        FETCH NEXT FROM schemaCur
        INTO @ColName,@ColDataTaype,@ColIsNulable,@ColDefault,@ColCharMaxlen,@ColNumPrec,@ColNumScal

        WHILE @@FETCH_STATUS = 0
        BEGIN
            SELECT @strSQLCol=''
            SELECT @strSQLCol= '['+@ColName+'] '+'[' + @ColDataTaype +'] '

            IF @ColDataTaype='nvarchar' or @ColDataTaype='char'  or @ColDataTaype='varchar' or @ColDataTaype='vchar'
                BEGIN
                    SELECT @strSQLCol=@strSQLCol+ '(' + @ColCharMaxlen +') '
                END 
            ELSE IF @ColDataTaype='numeric' or @ColDataTaype='decimal' 
                BEGIN
                    SELECT @strSQLCol=@strSQLCol +'(' + @ColNumPrec +',' +@ColNumScal + ') '
                END 

            IF @ColIsNulable='YES'
                BEGIN
                    SELECT @strSQLCol=@strSQLCol+ 'NULL '
                END 
            ELSE
                BEGIN
                    SELECT @strSQLCol=@strSQLCol+ ' NOT NULL '
                END 
            IF @ColDefault IS NOT NULL
                BEGIN
                    SELECT @strSQLCol=@strSQLCol+ ' DEFAULT(' +@ColDefault + '),'
                END 
            ELSE
                BEGIN
                    SELECT @strSQLCol=@strSQLCol+ ' ,'
                END

            SELECT @strSQL=@strSQL+@strSQLCol
                --print @strSQL
            FETCH NEXT FROM schemaCur
            INTO @ColName,@ColDataTaype,@ColIsNulable,@ColDefault,@ColCharMaxlen,@ColNumPrec,@ColNumScal

        END

        CLOSE schemaCur
        DEALLOCATE schemaCur

        --print @strSQL
        SELECT @strSQL=left( @strSQL, len(@strSQL)-1)
        --print @strSQL

        IF EXISTS (SELECT * FROM sys.types WHERE IS_TABLE_TYPE = 1 AND name = 't_' +@TableName)
        BEGIN           
            EXEC('DROP TYPE t_' +@TableName )
        END

        SELECT @strSQL =  'CREATE TYPE t_' + @TableName + ' AS TABLE (' +  @strSQL + ')'
        --print @strSQL
        EXEC (@strSQL)
        SELECT @TableNames = SUBSTRING(@TableNames, CHARINDEX(',', @TableNames) + 1, LEN(@TableNames))
END
END

আপনি এটি এটি ব্যবহার করতে পারেন

এক্সিকিউটি স্প_ডাইফাইন টাইপআউটঅফট্যাবলস্মিমা 'টেবিল 1 নাম, টেবিলের নাম'


এই কোডটি আমার পক্ষে কাজ করে নি। "ব্যবহারকারী-সংজ্ঞায়িত ফাংশন, পার্টিশন ফাংশন এবং কলাম রেফারেন্সগুলিকে এই প্রসঙ্গে প্রকাশের অনুমতি দেওয়া হয় না।" এমনকি যদি এটি কাজ করে তবে দেখে মনে হয় না ডিবোও ব্যতীত স্কিমার হ্যান্ডেল করার মতো কিছু আছে।
MgSam

2

এরল্যান্ড সোমমারস্কোগের একটি বিস্তৃত নিবন্ধ রয়েছে যাতে কীভাবে টিভিপি ব্যবহার করতে হয় তা বর্ণনা করা হয়েছে।

একবার দেখুন, এটি মূল্য!

সংক্ষেপে, আপনি অ্যারোন বার্ট্র্যান্ডের পূর্ববর্তী উত্তরের মতো একটি বিদ্যমান ধরণ ব্যবহার করতে পারবেন না । তবে কমপক্ষে এটি একটি বাল্ক ট্রান্সফার ..


1

জিতেনের উত্তরের ভিত্তিতে, কয়েকটি যুক্তি স্থানগুলিতে সরলকরণ, identityকলামগুলির জন্য অ্যাকাউন্টিং (এর sys.পরিবর্তে সারণী ব্যবহার করে SCHEMEA)

CREATE PROCEDURE [dbo].[usp_DefineTypeFromTable]
@TableNames NVARCHAR(500)
AS
BEGIN

DECLARE @TableName NVARCHAR(100)
DECLARE @strSQL NVARCHAR(max)
DECLARE @strSQLCol NVARCHAR(1000)
DECLARE @ColName NVARCHAR(100)
DECLARE @ColDataTaype NVARCHAR(50)
DECLARE @ColDefault NVARCHAR(50)
DECLARE @ColIsNulable NVARCHAR(50)
DECLARE @ColFirst NVARCHAR(50)
DECLARE @ColSecond NVARCHAR(50)
DECLARE @ColID NVARCHAR(50)
DECLARE @ColCompute NVARCHAR(50)

IF LEN(@TableNames) > 0 SET @TableNames = @TableNames + ',' 
WHILE LEN(@TableNames) > 0 
    BEGIN
        SELECT @TableName = TRIM(LEFT(@TableNames, CHARINDEX(',', @TableNames) - 1))
        DECLARE schemaCur CURSOR FOR 
            SELECT  
                c.name as column_name,
                t.name as [type_name],
                c.is_nullable,
                convert(nvarchar(4000), object_definition(ColumnProperty(c.object_id, c.name, 'default'))) as column_default,
                CASE
                    WHEN c.collation_name IS NOT NULL THEN c.max_length 
                    WHEN t.name like 'datetime%' THEN c.scale
                    WHEN c.scale = 0 THEN NULL
                    ELSE c.precision
                END as firstValue,
                CASE
                    WHEN (c.scale = 0 or t.name like 'datetime%') THEN NULL
                    ELSE c.scale
                END as secondValue,
                c.is_identity, -- would be best to know seed,increment
                c.is_computed -- should really look up col definition. `convert(nvarchar(4000), object_definition(ColumnProperty(c.object_id, c.name, 'computed')))` as computed ?

            FROM sys.columns as c join 
                 sys.all_objects as o 
                    on c.object_id=o.object_id join
                 sys.types as t
                    on c.user_type_id=t.user_type_id
            WHERE
                o.type in ('U','V','TF','IF','TT') and --'S' to include built-in tables/types
                o.name = @TableName
            ORDER BY o.name, c.column_id
        OPEN schemaCur
        SELECT @strSQL=''
        FETCH NEXT FROM schemaCur
            INTO @ColName,@ColDataTaype,@ColIsNulable,@ColDefault,@ColFirst,@ColSecond,@ColID,@ColCompute
        WHILE @@FETCH_STATUS = 0 BEGIN
--            SELECT @strSQLCol=''
            SELECT @strSQLCol= '['+@ColName+'] '+'[' + @ColDataTaype +'] '
            IF @ColSecond is NULL
                BEGIN
                    IF @ColFirst is not NULL SELECT @strSQLCol += '(' + @ColFirst + ') '
                END 
            ELSE SELECT @strSQLCol += '(' + @ColFirst +',' +@ColSecond + ') '
            IF @ColID>0 SELECT @strSQLCol += ' IDENTITY(1,1)'
            IF @ColIsNulable>0 SELECT @strSQLCol += 'NULL'
                ELSE SELECT @strSQLCol += ' NOT NULL'
            IF @ColDefault IS NOT NULL SELECT @strSQLCol += ' DEFAULT(' +@ColDefault + '),'
                ELSE SELECT @strSQLCol += ','
            SELECT @strSQL += @strSQLCol
                --print @strSQL
            FETCH NEXT FROM schemaCur
            INTO @ColName,@ColDataTaype,@ColIsNulable,@ColDefault,@ColFirst,@ColSecond,@ColID,@ColCompute
        END

        CLOSE schemaCur
        DEALLOCATE schemaCur

        SELECT @strSQL=left(@strSQL, len(@strSQL)-1)

        IF EXISTS (SELECT * FROM sys.types WHERE IS_TABLE_TYPE = 1 AND name = 'tt_' +@TableName)
        BEGIN           
            EXEC('DROP TYPE tt_' +@TableName )
        END

        SELECT @strSQL = 'CREATE TYPE tt_' + @TableName + ' AS TABLE (' +  @strSQL + ')'
        -- print @strSQL
        EXEC (@strSQL)
        SELECT @TableNames = SUBSTRING(@TableNames, CHARINDEX(',', @TableNames) + 1, LEN(@TableNames))
    END
END
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.