سؤال

إنني أتطلع إلى إعادة صياغة الاستعلام أدناه إلى شيء أكثر قابلية للقراءة والتعديل.النصف الأول مطابق للنصف الثاني، باستثناء قاعدة البيانات التي تم الاستعلام عنها (على الرغم من أن أسماء الجداول هي نفسها.)

  SELECT
    Column 1 AS c1,
    ...
    Column N AS cN
  FROM
    database1.dbo.Table1

UNION

  SELECT
    'Some String' as c1,
    ...
    NULL as cN
  FROM
    database1.dbo.Table2

UNION

  SELECT
    Column 1 AS c1,
    ...
    Column N AS cN
  FROM
    database2.dbo.Table1

UNION

  SELECT
    'Some String' as c1,
    ...
    NULL as cN
  FROM
    database2.dbo.Table2

هذا الاستعلام هو تعريف جاف ويدعوني إلى إعادة كتابته، لكن ليس لدي أي فكرة عن كيفية ذلك!

يحرر:لا يمكننا استخدام linq ونرغب في الحصول على نتائج مميزة؛إنني أتطلع إلى جعل الاستعلام أصغر في حجم الملف الفعلي، وليس في النتائج التي يتم إرجاعها.

يحرر:قاعدة البيانات التي أقوم بالاستعلام عنها هي قاعدة بيانات ERP خاصة.إعادة الهيكلة ليست خيارا.

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

المحلول

وهذا هو نمط SQL جميلة القياسية. أحيانا يكون من السهل نقل inadvisedly OOP / مبادئ قانون الإجراءات مثل DRY إلى SQL، ولكنها ليست بالضرورة مفاهيم قابلة للتحويل.

وملاحظة مدى السهولة التي يمكن جروك تصميم منطقي كامل من الاستعلام، مقابل الصيد من خلال الوحدات الفرعية. إذا كان واحدا من subexpressions عمود إضافي، أو الأعمدة عكسه، فإنه يلتزم بها. هذا هو في الأساس عبارة SQL بسيط جدا لجروك كوحدة التنفيذ، حيث تفصيل ذلك أن التشويش عليه.

وعندما كنت التصحيح، انها في متناول اليد لتكون قادرة على استخدام المحرر الخيار تمييز النص إلى ممارسة انتقائية أجزاء من بيان - وهي تقنية لم تكن موجودة في قانون الإجراءات. OTOH، فإنه يمكن الحصول على الفوضى في محاولة لتعقب أسفل كل قطعة إذا فهي منتشرة في وجهات النظر الخ حتى CTEs يمكن أن تجعل هذا غير مريح.

نصائح أخرى

سأقوم بالتوقف هنا، وأقول، بناءً على المعلومات التي قدمتها لنا؛

هذا جيد بقدر ما سيحصل عليه

واحد الأداء طرف أن أرى قبالة الخفافيش تستخدم UNION ALL بدلا من UNION إلا إذا كنت تريد عمدا سجلات متميزة. وهناك UNION بسيطة القضاء على التكرار الذي يستغرق وقتا طويلا. UNION ALL لا تفعل ذلك.

هل يمكن إعادة كتابتها مع SQL ديناميكية وحلقة ولكن أعتقد أن النتيجة ستكون أسوأ. إذا كان هناك ما يكفي كود مكررة لتبرير النهج SQL الديناميكي، ثم اعتقد انه يمكن تبريره.

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

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

ما هي المشكلة؟ طويل جدا؟ التكرار أيضا؟

وأحيانا تحصل SQL القبيح - وليس هناك الكثير مما يمكن القيام به حيال ذلك.

وأنا لا أرى أي طريقة لتنظيفه إلا إذا كنت تريد استخدام طرق منفصلة ثم الاتحاد معا.

واصوت لوجهات النظر، والتي تفرض شبه ما يكفي من فوق الصفر (حسنا، ربما صغيرة تكلفة لمرة والترجمة ولكن هذا يجب أن يكون كل شيء). ثم procs الخاص أصبح شيئا من النموذج

SELECT * FROM database1.view1
UNION
SELECT * FROM database1.view2
UNION
SELECT * FROM database2.view1
UNION
SELECT * FROM database2.view2

وأنا لست متأكدا إذا كنت تريد أن تتكثف ذلك إلى أبعد من ذلك، على الرغم من أنني أتوقع معظم المنصات لن تتسامح مع ذلك.

في موضوع ديناميكي SQL - هنا هو عينة - ليس متأكدا مما اذا كان أي أفضل. ولديك صالح فقط لكتابة قائمة SELECT مرة واحدة.

DECLARE @Select1 varchar(1000)
DECLARE @Select2 varchar(1000)

DECLARE @SQL varchar(4000)


SET @Select1 = 'SELECT
    Column 1 AS c1,
    ...
    Column N AS cN'


SET @Select2 = 'SELECT
    ''Some String'' as c1,
    ...
    NULL as cN'


SET @SQL = @Select1 + ' FROM database1.dbo.Table1 '

SET @SQL = @SQL + ' UNION ' + @Select2 + ' FROM database1.dbo.Table2 '

SET @SQL = @SQL + ' UNION ' + @Select1 + ' FROM database2.dbo.Table1 '

SET @SQL = @SQL + ' UNION ' + @Select2 + ' FROM database2.dbo.Table2 '


EXEC @SQL

وإذا كان كل procs تبدو مثل هذا - وربما كنت قد حصلت على مشكلة المعمارية

.

هل جميع مكالماتك إلى table2 يكون مجرد حقل واحد مفيد؟ (وبسبب UNION، ينتهي بعد صف واحد فقط؟)

وI الثانية تماما فكرة الذهاب مع SQL معلمات الديناميكي و / أو توليد رمز لهذه المهمة، وحتى الذهاب إلى أبعد من ذلك إنشاء قائمة العمود حيوي باستخدام INFORMATION_SCHEMA. هذا ليس بالضبط ما تحتاجه لكنه بداية (قد تولد خارج جدول قواعد البيانات والجداول):

DECLARE @template AS varchar(MAX)
SET @template = 'SELECT {@column_list} FROM {@database_name}.dbo.{@table_name}'
DECLARE @column_list AS varchar(MAX)

SELECT @column_list = COALESCE(@column_list + ',', '') + COLUMN_NAME
FROM database1.dbo.INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = @table_name
ORDER BY ORDINAL_POSITION

DECLARE @sql AS varchar(MAX)
SET @sql = @template
SET @sql = REPLACE(@sql, '{@column_list}', @column_list)
SET @sql = REPLACE(@sql, '{@database_name}', @database_name)
SET @sql = REPLACE(@sql, '{@table_name}', @table_name)

واعتمادا على عدد الصفوف التي يتم إرجاعها، قد يكون من الأفضل استخدام UNION ALL على يختار مع استعلام متميز حدد حوله. رأيت مشكلة مماثلة من قبل، وكان خطط التنفيذ مختلفة لاثنين من أنماط مختلفة

SELECT DISTINCT subquery.c1, subquery.cN
FROM
(
SELECT Column 1 AS c1, Column N AS cN FROM database1.dbo.Table1
UNION ALL
SELECT 'Some String' as c1, NULL as cN FROM database1.dbo.Table2
UNION ALL
SELECT Column 1 AS c1, Column N AS cN FROM database2.dbo.Table1
UNION ALL
SELECT 'Some String' as c1, NULL as cN FROM database2.dbo.Table2
) subquery
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top