في T-SQL كيفية عرض الأعمدة لاسم الجدول المعطى؟
-
25-09-2019 - |
سؤال
أحاول إدراج جميع الأعمدة من أي جدول مغامرات أختار. ما هي عبارة 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 = (مهما كانت مرورها) ، أو لا.