سؤال

أحاول إدراج جميع الأعمدة من أي جدول مغامرات أختار. ما هي عبارة T-SQL أو Proc المخزنة التي يمكنني تنفيذها لرؤية هذه القائمة بجميع الأعمدة؟ أرغب في استخدام تطبيق الويب الخاص بي C# لإدخال معلمة إدخال واحدة = table_name ثم الحصول على قائمة بجميع Column_names كإخراج. في الوقت الحالي ، أحاول تنفيذ SP_Columns المخزنة التي تعمل ، لكن لا يمكنني الحصول على عمود واحد فقط مع SELECT و EXEC مجتمعة. لا أحد يعرف كيفية القيام بذلك؟

شكرا للجميع على كل ردودك ، ولكن لا شيء من إجاباتك تفعل ما أحتاجه. اسمحوا لي أن أشرح مشكلتي أكثر بالنسبة لك. الاستعلام أدناه يعيد ما أحتاجه. لكن مشكلتي هي دمج هذا المنطق في SP يأخذ معلمة إدخال. إذن هنا هو بيان SQL الناجح:

select col.name from sysobjects obj inner join syscolumns col 
    on obj.id = col.id
    where obj.name = 'AddressType' 
     order by obj.name

وحاليًا يبدو SP الخاص بي:

CREATE PROCEDURE [dbo].[getColumnNames]
    @TableName VarChar(50)
    AS

    BEGIN
    SET NOCOUNT ON;
    SET @TableName = RTRIM(@TableName)
    DECLARE @cmd AS NVARCHAR(max)
    SET @cmd = N'SELECT col.name from sysobjects obj ' +
    'inner join syscolumns col on obj.id = col.id ' +
    'where obj.name = ' + @TableName
    EXEC sp_executesql @cmd
    END

لكني أدير ما سبق

exec getColumnNames 'AddressType'

ويعطيني خطأ:

Invalid column name 'AddressType'

كيف أنجز هذا؟

هل كانت مفيدة؟

المحلول

لا تحتاج إلى إنشاء البيان كسلسلة - في الواقع ، هذا ما يفسدك. جرب هذا:

CREATE PROCEDURE [dbo].[getColumnNames] @TableName VarChar(50) AS

BEGIN
SET NOCOUNT ON;
SELECT col.name FROM sysobjects obj 
INNER JOIN syscolumns col ON obj.id = col.id 
WHERE obj.name = @TableName
END

نصائح أخرى

select * from sys.columns where object_id = object_id(@tablename);

لعرض المعلومات ل database.dbo.yourtable جرب هذا:

SELECT
    *
    FROM INFORMATION_SCHEMA.COLUMNS
    WHERE 
        TABLE_CATALOG   ='database'
        AND TABLE_SCHEMA='dbo'
        AND TABLE_NAME  ='yourtable'
    ORDER BY ORDINAL_POSITION

تعديل بناءً على تحرير OP

لا تحتاج إلى SQL ديناميكي ، فقط استخدم المعلمة المحددة:

CREATE PROCEDURE [dbo].[getColumnNames]
@TableName VarChar(50)
AS
BEGIN
    SET NOCOUNT ON;
    DECLARE @Rows         int
           ,@ReturnValue  int
    SET @ReturnValue=0
    SELECT
        col.name 
        FROM sysobjects            obj 
            inner join syscolumns  col on obj.id = col.id 
        WHERE obj.name = @TableName
        ORDER BY obj.name
    SELECT @Rows=@@ROWCOUNT
    IF @Rows=0
    BEGIN
        SET @ReturnValue= 1  --table not found!!
    END
    RETURN @ReturnValue 

END

إذا قمت بفحص قيمة الإرجاع والحصول على 1 ، فلن يتم العثور على أي جدول مطابقة لمعلمة tablename المعطاة. يمكنك استخدام هذا لإعطاء رسالة خطأ في التطبيق.

SELECT *
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'TableName' AND TABLE_CATALOG = 'DatabaseName'

استخدم إجابة أو استخدام Remus Rusanu SqlConnection.GetSchema() وظيفة من رمز C# الخاص بك

رد على الخاص بك تحرير سؤال:

لا يعمل البرنامج النصي الخاص بك لأنك تقوم ببناء سلسلة ديناميكية ، وضمن تلك السلسلة الديناميكية ، يجب عليك إضافة علامات اقتباس إلى السلسلة التي تضعها في جملة مكانك. سيكون الرمز المنقح:

BEGIN 
SET NOCOUNT ON; 
SET @TableName = RTRIM(@TableName) 
DECLARE @cmd AS NVARCHAR(max) 
SET @cmd = N'SELECT col.name from sysobjects obj ' + 
'inner join syscolumns col on obj.id = col.id ' + 
'where obj.name = ''' + @TableName + ''''
EXEC sp_executesql @cmd 
END 

ومع ذلك ، لماذا أنت ترتدي سلسلة ديناميكية؟ هذا من شأنه أن يفعل نفس الشيء ولا يتطلب النفقات العامة لـ SQL الديناميكي:

BEGIN 
SET NOCOUNT ON; 
SET @TableName = RTRIM(@TableName) 
SELECT col.name from sysobjects obj
inner join syscolumns col on obj.id = col.id
where obj.name = @TableName 
END 

إذا كنت قلقًا بشأن حقن SQL ، فليس مشكلة هنا - إما obj.name = (مهما كانت مرورها) ، أو لا.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top