شرح - update mysql




حدد جميع الأعمدة باستثناء واحد في MySQL؟ (19)

أتفق مع الحل "البسيط" لإدراج جميع الأعمدة ، لكن هذا يمكن أن يكون عبئًا ، والأخطاء التفسيرية يمكن أن تسبب الكثير من الوقت الضائع. أستخدم دالة "getTableColumns" لاسترداد أسماء أعمالي المناسبة للصق في استعلام. إذن كل ما علي فعله هو حذف أولئك الذين لا أريدهم.

CREATE FUNCTION `getTableColumns`(tablename varchar(100)) 
          RETURNS varchar(5000) CHARSET latin1
BEGIN
  DECLARE done INT DEFAULT 0;
  DECLARE res  VARCHAR(5000) DEFAULT "";

  DECLARE col  VARCHAR(200);
  DECLARE cur1 CURSOR FOR 
    select COLUMN_NAME from information_schema.columns 
    where TABLE_NAM[email protected] AND TABLE_SCHEMA="yourdatabase" ORDER BY ORDINAL_POSITION;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
  OPEN cur1;
  REPEAT
       FETCH cur1 INTO col;
       IF NOT done THEN 
          set res = CONCAT(res,IF(LENGTH(res)>0,",",""),col);
       END IF;
    UNTIL done END REPEAT;
  CLOSE cur1;
  RETURN res;

النتيجة الخاصة بك بإرجاع سلسلة محددة بفواصل ، على سبيل المثال ...

COL1، col2، COL3، col4 ... col53

أحاول استخدام عبارة محددة للحصول على جميع الأعمدة من جدول MySQL معين باستثناء واحد. هل هناك طريقة بسيطة للقيام بذلك؟

تعديل: يوجد 53 عمودًا في هذا الجدول (ليس MY DESIGN)


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

SET @SQL = CONCAT('SELECT ', (SELECT GROUP_CONCAT(CONCAT("`", COLUMN_NAME, "`")) FROM
INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'users' AND COLUMN_NAME NOT IN ('id')), ' FROM users');
PREPARE stmt1 FROM @SQL;
EXECUTE stmt1;

أوافق على أنه ليس كافياً Select * ، إذا كان هذا الشخص الذي لا تحتاج إليه ، كما هو مذكور في مكان آخر ، هو BLOB ، فأنت لا تريد أن تتسلل إلى الأعلى.

أود إنشاء عرض مع البيانات المطلوبة ، ثم يمكنك Select * في الراحة - إذا كان برنامج قواعد البيانات يدعمها. آخر ، ضع البيانات الضخمة في جدول آخر.


أود أن أضيف وجهة نظر أخرى لحل هذه المشكلة ، خاصة إذا كان لديك عدد صغير من الأعمدة لإزالتها.

يمكنك استخدام أداة DB مثل MySQL Workbench من أجل توليد العبارة المختارة لك ، لذلك عليك فقط إزالة تلك الأعمدة يدويًا للبيان الذي تم إنشاؤه ونسخه إلى برنامج SQL النصي.

في MySQL Workbench طريقة توليد ذلك هي:

انقر بزر الماوس الأيمن على الجدول -> إرسال إلى محرر Sql -> حدد كل بيان.


إذا كان العمود واحدًا دائمًا ، فيمكنك إنشاء ملف شخصي لا يتضمنه.

خلاف ذلك ، لا لا أعتقد ذلك.


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

على سبيل المثال

SELECT *, NULL AS salary FROM users

استنادًا إلىMahomedalid answer ، قمت ببعض التحسينات لدعم "تحديد كل الأعمدة باستثناء بعض في mysql"

SET @database    = 'database_name';
SET @tablename   = 'table_name';
SET @cols2delete = 'col1,col2,col3';

SET @sql = CONCAT(
'SELECT ', 
(
    SELECT GROUP_CONCAT( IF(FIND_IN_SET(COLUMN_NAME, @cols2delete), NULL, COLUMN_NAME ) )
    FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @tablename AND TABLE_SCHEMA = @database
), 
' FROM ',
@tablename);

SELECT @sql;

إذا كان لديك الكثير من cols ، استخدم هذا sql لتغيير group_concat_max_len

SET @@group_concat_max_len = 2048;

الجواب الذي نشره Mahomedalid لديه مشكلة صغيرة:

تم استبدال رمز الوظيفة الداخلي " <columns_to_delete>, " بواسطة "" ، هذا الاستبدال لديه مشكلة إذا كان الحقل لاستبدال آخر واحد في سلسلة concat بسبب آخر واحد ليس لديه فاصلة char "،" و لا تتم إزالتها من السلسلة.

اقتراحي:

SET @sql = CONCAT('SELECT ', (SELECT REPLACE(GROUP_CONCAT(COLUMN_NAME),
                  '<columns_to_delete>', '\'FIELD_REMOVED\'')
           FROM INFORMATION_SCHEMA.COLUMNS
           WHERE TABLE_NAME = '<table>'
             AND TABLE_SCHEMA = '<database>'), ' FROM <table>');

استبدال <table> و <database> و `

يتم استبدال العمود الذي تم استبعاده بالسلسلة "FIELD_REMOVED" في حالتي لأن ذلك كان يحاول حفظ الذاكرة الآمنة. (الحقل الذي أقوم بإزالته هو BLOB من حوالي 1MB)


بينما أتفق مع إجابة توماس (+1 ؛)) ، أود أن أضيف التحذير بأنني سأفترض أن العمود الذي لا تريده يحتوي على أي بيانات. إذا كان يحتوي على كميات هائلة من النص ، أو xml أو النقط الثنائية ، فاخذ الوقت لتحديد كل عمود على حدة. سوف أداؤكم يعانون خلاف ذلك. في صحتك!


حدد * هو antipattern SQL. يجب عدم استخدامه في رمز الإنتاج لأسباب عديدة منها:

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

هذا يعني أنك ربما ترسل بيانات أكثر مما تحتاج ، مما يؤدي إلى اختناقات الخادم والشبكة. إذا كان لديك صلة داخلية ، فإن فرص إرسال بيانات أكثر مما تحتاج إليه هي 100٪.

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

يمكن أن كسر وجهات النظر (أنا أعلم أن هذا صحيح في خادم SQl ، قد يكون أو لا يكون صحيحا في الخلية).

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

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

قد يكسر المشغلات. قد يكون من الصعب تشخيص مشاكل الزناد.

أضف كل هذا في الوقت الذي تستغرقه لإضافة أسماء الأعمدة (يمكنك أن تكون لديك واجهة تسمح لك بسحب أسماء الأعمدة (أعلم أنني أفعل في SQL Server ، أراهن أن هناك طريقة هل هذا هو بعض الأدوات التي تستخدمها لكتابة استعلامات mysql.) دعونا نرى ، "يمكنني أن يسبب مشاكل الصيانة ، ويمكنني أن يسبب مشاكل الأداء ويمكن أن يسبب مشاكل تكامل البيانات ، ولكن يا أنا أنقذت خمس دقائق من وقت التطوير." حقا وضعت للتو في الأعمدة المحددة التي تريدها.

أقترح عليك أيضًا قراءة هذا الكتاب: http://www.amazon.com/SQL-Antipatterns-Programming-Pragmatic-Programmers-ebook/dp/B00A376BB2/ref=sr_1_1?s=digital-text&ie=UTF8&qid=1389896688&sr=1-1&keywords=sql+antipatterns


فقط افعل

SELECT * FROM table WHERE whatever

ثم قم بإسقاط العمود في لغة البرمجة المفضلة لديك: php

while (($data = mysql_fetch_array($result, MYSQL_ASSOC)) !== FALSE) {
   unset($data["id"]);
   foreach ($data as $k => $v) { 
      echo"$v,";
   }      
}

في البداية اعتقدت أنك تستطيع استخدام تعبيرات عادية ، ولكن بما أنني كنت أقرأ مستندات MYSQL يبدو أنك لا تستطيع ذلك. إذا كنت أنت سأستخدم لغة أخرى (مثل PHP) لإنشاء قائمة بالأعمدة التي تريد الحصول عليها ، فقم بتخزينها كسلسلة ثم استخدمها لإنشاء SQL.


في تعريفات mysql (دليل) لا يوجد شيء من هذا القبيل. ولكن إذا كان لديك عدد كبير جدًا من الأعمدة col1 ، ... ، col100 ، يمكن أن يكون ما يلي مفيدًا:

mysql> CREATE TEMPORARY TABLE temp_tb SELECT * FROM orig_tb;
mysql> ALTER TABLE temp_tb DROP col_x;
mysql> SELECT * FROM temp_tb;

قد يكون لدي حل ل Jan Koritak أشار إلى التناقض

SELECT CONCAT('SELECT ',
( SELECT GROUP_CONCAT(t.col)
FROM
(
    SELECT CASE
    WHEN COLUMN_NAME = 'eid' THEN NULL
    ELSE COLUMN_NAME
    END AS col 
    FROM INFORMATION_SCHEMA.COLUMNS 
    WHERE TABLE_NAME = 'employee' AND TABLE_SCHEMA = 'test'
) t
WHERE t.col IS NOT NULL) ,
' FROM employee' );

الطاولة :

SELECT table_name,column_name 
FROM INFORMATION_SCHEMA.COLUMNS 
WHERE TABLE_NAME = 'employee' AND TABLE_SCHEMA = 'test'

================================

table_name  column_name
employee    eid
employee    name_eid
employee    sal

================================

نتيجة الاستعلام:

'SELECT name_eid,sal FROM employee'

مشكلتي الرئيسية هي الأعمدة العديدة التي أحصل عليها عند الانضمام إلى الجداول. في حين أن هذه ليست الإجابة على سؤالك (كيفية تحديد جميع الأعمدة باستثناء بعض الأعمدة من جدول واحد ) ، أعتقد أنه من الجدير بالذكر أنه يمكنك تحديد table. للحصول على جميع الأعمدة من جدول معين ، بدلاً من التحديد فقط.

في ما يلي مثال على كيف يمكن أن يكون ذلك مفيدًا جدًا:

select users.*, phone.meta_value as phone, zipcode.meta_value as zipcode

from users

left join user_meta as phone
on ( (users.user_id = phone.user_id) AND (phone.meta_key = 'phone') )

left join user_meta as zipcode
on ( (users.user_id = zipcode.user_id) AND (zipcode.meta_key = 'zipcode') )

والنتيجة هي كل الأعمدة من جدول المستخدمين ، واثنين من الأعمدة الإضافية التي انضمت من جدول التعريف.


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

لذلك أقترح عليك كتابة اسم كل عمود في البيان (باستثناء الاسم الذي لا تريده).

SELECT
    col1
    , col2
    , col3
    , col..
    , col53

FROM table

هل سيكون "عرض" أفضل في هذه الحالة؟

CREATE VIEW vwTable
as  
SELECT  
    col1  
    , col2  
    , col3  
    , col..  
    , col53  
FROM table

يمكنك استخدام وصف my_table واستخدام نتائج ذلك لإنشاء عبارة SELECT بشكل حيوي.


يمكنك ان تفعل:

SELECT column1, column2, column4 FROM table WHERE whatever

دون الحصول على العمود 3 ، على الرغم من أنك ربما كنت تبحث عن حل أكثر عمومية؟





select