2009-01-05 11 views
41

क्या कोई RDBMS है जो SELECT * EXCEPT जैसे कुछ लागू करता है? मैं जो कुछ भी कर रहा हूं वह एक विशिष्ट टेक्स्ट/बीएलओबी फ़ील्ड को छोड़कर सभी फ़ील्ड प्राप्त कर रहा है, और मैं बस बाकी सब कुछ चुनना चाहता हूं।चयन * EXCEPT

लगभग दैनिक मैं अपने सहकर्मियों को शिकायत है कि कोई इस को लागू करना चाहिए ... यह बहुत कष्टप्रद है कि यह मौजूद नहीं है है।

संपादित करें: मैं SELECT * के लिए सभी की चिंता को समझता हूं। मुझे SELECT * से जुड़े जोखिमों को पता है। हालांकि, कम से कम मेरी स्थिति में, किसी भी उत्पादन स्तर कोड, या यहां तक ​​कि विकास स्तर कोड के लिए भी उपयोग नहीं किया जाएगा; सख्ती से डीबगिंग के लिए, जब मुझे आसानी से सभी मूल्यों को देखने की आवश्यकता होती है।

मैं टिप्पणी, जहाँ मैं काम से कुछ में कहा गया है किया है कड़ाई से एक कमांडलाइन की दुकान है, SSH पर सब कुछ कर। यह यह मुश्किल किसी भी जीयूआई उपकरण (डेटाबेस के लिए बाहरी कनेक्शन की अनुमति नहीं है), आदि आदि

सुझाव के लिए धन्यवाद, हालांकि उपयोग करने के लिए बनाता है।

+0

EXCEPT कीवर्ड SQL सर्वर के भीतर मौजूद है, हालांकि इसका उपयोग यह नहीं है कि आप अपने प्रश्न में कैसा चाहें। यह दो परिणामों के बीच एक अंतर संघ बनाता है जो आपको पहले परिणाम में मौजूद "रिकॉर्ड" का परिणाम देता है लेकिन दूसरे परिणाम –

+3

में मौजूद नहीं है यह चूसता है कि यह अस्तित्व में नहीं है। – VISQL

+1

संभव डुप्लिकेट [एसक्यूएल SELECT \ * \ का उपयोग कर कॉलम को बाहर निकालें [कॉलम ए को छोड़कर \]] tableA से?] (Http://stackoverflow.com/questions/729197/sql-exclude-a-column-using-select-except- columna-from-tablea) – billinkc

उत्तर

25

शामिल नहीं है बनाएँ, यह एक अच्छा विचार नहीं है किसी प्रश्न में ऐसा करने के लिए क्योंकि जब कोई भविष्य में तालिका संरचना बदलता है तो यह समस्याएं प्रवण होता है। हालांकि, वहाँ यह करने के लिए एक रास्ता है ... और मैं विश्वास नहीं कर सकता मैं वास्तव में इस सुझाव दे रही है, लेकिन वास्तविक सवाल का जवाब देने की भावना में ...

गतिशील एसक्यूएल के साथ है ... इस "विवरण" कॉलम को छोड़कर सभी कॉलम करता है। आप इसे आसानी से किसी फ़ंक्शन या संग्रहीत प्रो में बदल सकते हैं।

declare @sql varchar(8000), 
    @table_id int, 
    @col_id int 

set @sql = 'select ' 

select @table_id = id from sysobjects where name = 'MY_Table' 

select @col_id = min(colid) from syscolumns where id = @table_id and name <> 'description' 
while (@col_id is not null) begin 
    select @sql = @sql + name from syscolumns where id = @table_id and colid = @col_id 

    select @col_id = min(colid) from syscolumns where id = @table_id and colid > @col_id and name <> 'description' 
    if (@col_id is not null) set @sql = @sql + ',' 
    print @sql 
end 

set @sql = @sql + ' from MY_table' 

exec @sql 
+9

और वास्तविक प्रश्न का उत्तर देने की भावना में, आप पुरस्कार जीतते हैं। –

+1

मैं वास्तव में कई कारणों से सोच सकता हूं कि आपको पागल होने के बिना ऐसा करने की आवश्यकता क्यों हो सकती है। इसके अलावा, यह एक दिलचस्प सवाल था, मुद्दों के बावजूद, यह पता लगाने में बस मजेदार था :) – Jasmine

+1

सबसे पहले, इस बात का चयन करने के लिए धन्यवाद कि व्यक्ति को क्या करना चाहिए या नहीं। ऐसा करने के लिए एक प्रमुख परिदृश्य एक दृश्य तैयार करेगा, जिसे आप बदलते हुए तालिका कॉलम चुनना चाहते हैं, और वे अन्य चुनिंदा वक्तव्यों में उपयोग करेंगे जो विशिष्ट कॉलम चुनते हैं। –

5

SELECT * से दूर रहें, आप स्वयं को परेशानी के लिए सेट कर रहे हैं। हमेशा निर्दिष्ट करें कि आप कौन से कॉलम चाहते हैं। यह वास्तव में काफी ताज़ा है कि आप जिस "फीचर" के लिए पूछ रहे हैं वह मौजूद नहीं है।

+0

सौभाग्य से, हमारी टेबल लगभग कभी नहीं बदली जाती है। मैं विशेष रूप से डीबगिंग समस्याओं के लिए इस बारे में सोच रहा हूं, जहां मुझे बीएलओबी को छोड़कर अन्य सभी क्षेत्रों की आवश्यकता है। उस विशिष्ट मामले में –

+0

, मैं मानता हूं कि यह अच्छा होगा। –

+0

यहां ऑपरेटिंग शब्द * लगभग * है। साथ ही, कोई भी अच्छा एसक्यूएल टूल आपको इस तरह के कॉन्ट्रैक्शन के साथ भाषा को प्रदूषित किए बिना आप जो भी चाहते हैं उसे क्लिक और चुनने की अनुमति देगा। –

2

मेरा मानना ​​है कि इसके लिए तर्क मौजूदा नहीं है कि एक प्रश्न के लेखक को (प्रदर्शन के लिए) केवल अनुरोध करना चाहिए कि वे क्या देख रहे हैं (और इसलिए पता है कि कॉलम निर्दिष्ट करने के लिए क्या हैं) - अगर कोई भविष्य में कुछ और ब्लब्स जोड़ता है, आप उन संभावित बड़े क्षेत्रों को वापस खींच रहे होंगे जिनकी आपको आवश्यकता नहीं है।

1

जैसा कि अन्य कह रहे हैं: चयन * एक बुरा विचार है।

कुछ कारणों:

  1. जाओ सिर्फ तुम क्या जरूरत है
  2. अनुक्रमण ((कुछ भी अधिक बर्बादी है) सूचकांक आपको क्या चाहिए और वह भी बहुत जल्द मिल सकता है आप गैर का एक समूह के लिए पूछते हैं। -indexed कॉलम भी आपकी क्वेरी योजनाओं भुगतना होगा।
+0

मैं आपके सेकंड पॉइंट पर सहमत नहीं हूं, क्योंकि कॉलम लाने से पहले इंडेक्सिंग और निष्पादन योजनाओं के साथ कुछ भी नहीं करना है। यदि आप कॉलम द्वारा तालिकाओं में शामिल होना चाहते हैं या किसी योग्य समय में कॉलम (WHERE) पर डेटा प्रतिबंधित करना चाहते हैं, तो आप एक कॉलम में एक अनुक्रमणिका जोड़ते हैं। जब आप उन्हें शामिल करके पांच टेबल का चयन करते हैं, तो यह वास्तव में कोई फर्क नहीं पड़ता कि आप एक या 200 कॉलम चुनते हैं (यह केवल डेटा लाने का मामला है)। – bobbel

+1

@ बॉबबेल मुझे जोर देना चाहिए कि इंडेक्स वांछित रिकॉर्ड ढूंढने से परे पुनर्प्राप्ति में बिल्कुल सुधार कर सकते हैं, * यदि * वे अनुरोधित कॉलम को कवर करते हैं। इंडेक्स को कवर करने से संपूर्ण क्वेरी/जॉइन/इत्यादि का जवाब देकर बड़े प्रदर्शन में सुधार हो सकता है। इंडेक्स से ही - सूचकांक उत्पन्न करने वाले अंतर्निहित डेटा पर जाकर। –

23

मेज पर एक दृश्य के रूप में अन्य लोगों ने कहा जो ब्लॉब स्तंभों

+1

+1: यह काफी उचित है - और कोई चयन * यहां भी अनुमति नहीं है। –

+1

स्रोत तालिका में परिवर्तन होने पर दृश्य को संशोधित करने की आवश्यकता है। यदि आप उस पर SELECT * का उपयोग करने जा रहे हैं, तो साथ ही उन स्तंभों का चयन भी कर सकते हैं जिन्हें आप वास्तव में शुरू करना चाहते हैं। –

+1

यह आपको उन स्तंभों को ऊपर और ऊपर टाइप करने से बचाता है। डीबगिंग में डेवलपर के उपयोग के लिए यह एक बुरा विचार नहीं है। –

0
declare @sql nvarchar(max) 
     @table char(10) 
set @sql = 'select ' 
set @table = 'table_name' 

SELECT @sql = @sql + '[' + COLUMN_NAME + '],' 
FROM INFORMATION_SCHEMA.Columns 
WHERE TABLE_NAME = @table 
    and COLUMN_NAME <> 'omitted_column_name' 
SET @sql = substring(@sql,1,len(@sql)-1) + ' from ' + @table 

EXEC (@sql); 
5

कोई आरडीबीएमएस कि चुनें * की तरह कुछ

हाँ छोड़कर लागू करता है! वास्तव में संबंधपरक भाषा Tutorial D को रखने के बजाय हटाए जाने वाले गुणों के संदर्भ में प्रक्षेपण को व्यक्त करने की अनुमति देता है उदा।

my_relvar { ALL BUT description } 

वास्तव में, एसक्यूएल के SELECT * को इसके समकक्ष { ALL BUT } है।

एसक्यूएल के लिए आपके प्रस्ताव एक योग्य एक है लेकिन मैंने सुना है यह पहले से ही उपयोगकर्ताओं के समूह द्वारा एसक्यूएल मानक की समिति के लिए डाल दिया गया है और खारिज कर दिया विक्रेता के समूह :(द्वारा

यह भी explicitly requested for SQL Server लेकिन अनुरोध किया गया है के रूप में 'ठीक नहीं होगा' बंद हो गया।

9

डीबी 2 इस के लिए अनुमति देता है। कॉलम Hidden की एक विशेषता/विनिर्देशक है।

syscolumns documentation

से

छिपे
CHAR (1) डिफ़ॉल्ट के साथ शून्य नहीं 'एन'
बताता है कि क्या स्तंभ परोक्ष छिपा हुआ है:

पी आंशिक रूप से छिपा। स्तंभ को स्पष्ट रूप से SELECT * से छुपाया गया है।

एन छुपा नहीं है। कॉलम सभी SQL कथनों के लिए दृश्यमान है।

Create table documentation अपने स्तंभ बनाने के हिस्से के रूप में, आप

Implicitly Hidden Columns से एक उदाहरण DDL इस प्रकार

CREATE TABLE T1 
(C1 SMALLINT NOT NULL, 
C2 CHAR(10) IMPLICITLY HIDDEN, 
C3 TIMESTAMP) 
IN DB.TS; 

IMPLICITLY HIDDEN संशोधक में निर्दिष्ट करना होगा यह क्षमता इस तरह के एक सौदा निर्माता की गोद लेने ड्राइव करने के लिए है या नहीं डीबी 2 भविष्य के पाठकों के लिए एक अभ्यास के रूप में छोड़ दिया गया है।

0

यह एक पुराना सवाल है, लेकिन मुझे आशा है कि यह अभी भी सहायक हो सकता है।

DECLARE @SQL NVARCHAR(MAX) 
SELECT @SQL = COALESCE(@SQL + ', ', ' ') + name FROM sys.columns WHERE name <> 'colName' AND object_id = (SELECT id FROM sysobjects WHERE name = 'tblName') 
SELECT @SQL = 'SELECT ' + @SQL + ' FROM ' + 'tblName' 
EXEC sp_executesql @SQL 

संग्रहित प्रक्रिया:

usp_SelectAllExcept 'tblname', 'colname'

ALTER PROCEDURE [dbo].[usp_SelectAllExcept] 
(
    @tblName SYSNAME 
,@exception VARCHAR(500) 
) 
AS 

DECLARE @SQL NVARCHAR(MAX) 

SELECT @SQL = COALESCE(@SQL + ', ', ' ') + name from sys.columns where name <> @exception and object_id = (Select id from sysobjects where name = @tblName) 
SELECT @SQL = 'SELECT ' + @SQL + ' FROM ' + @tblName 

EXEC sp_executesql @SQL 
0

मैं क्या @Glen HASHBYTES के साथ मेरे जीवन में ढील के लिए पूछता है की तरह कुछ की जरूरत()।

मेरी प्रेरणा @ जैस्मीन और @ ज़रुब्बाबेल उत्तर थी। मेरे मामले में मेरे पास अलग-अलग स्कीमा हैं, इसलिए sys.objects पर एक ही टेबल नाम एक से अधिक बार प्रकट होता है। के रूप में यह एक ही परिदृश्य के साथ किसी की मदद कर सकते हैं, यहाँ यह जाता है:

ALTER PROCEDURE [dbo].[_getLineExceptCol] 

@table SYSNAME, 
@schema SYSNAME, 
@LineId int, 
@exception VARCHAR(500) 

AS 

DECLARE @SQL NVARCHAR(MAX) 

BEGIN 

SET NOCOUNT ON; 

SELECT @SQL = COALESCE(@SQL + ', ', ' ') + name 
FROM sys.columns 
WHERE name <> @exception 
AND object_id = (SELECT object_id FROM sys.objects 
       WHERE name LIKE @table 
       AND schema_id = (SELECT schema_id FROM sys.schemas WHERE name LIKE @schema)) 

SELECT @SQL = 'SELECT ' + @SQL + ' FROM ' + @schema + '.' + @table + ' WHERE Id = ' + CAST(@LineId AS nvarchar(50)) 

EXEC(@SQL) 
END 
GO 
0

अस्थायी तालिका विकल्प यहाँ, बस आवश्यकता नहीं कॉलम ड्रॉप और बदल अस्थायी तालिका से * का चयन करें।

/* Get the data into a temp table */ 
    SELECT * INTO #TempTable 
    FROM 
    table 

/* Drop the columns that are not needed */ 
    ALTER TABLE #TempTable 
    DROP COLUMN [columnname] 

SELECT * from #TempTable 
0

पूर्णता के लिए के लिए, यह DremelSQL बोली में संभव है, की तरह कुछ कर रही:

WITH orders AS (SELECT 5 as order_id, "foobar12" as item_name, 800 as quantity) SELECT * EXCEPT (order_id) FROM orders;

+-----------+----------+ | item_name | quantity | +-----------+----------+ | foobar12 | 800 | +-----------+----------+

वहाँ भी एक और तरीका है बिना यह here करने के लिए हो रहा है Dremel।

1

हाँ, अंत में वहाँ है :) एसक्यूएल मानक 2016 को परिभाषित करता है Polymorphic Table Functions

एसक्यूएल: 2016 का परिचय बहुरूपी तालिका कार्य (PTF) कि परिणाम प्रकार अग्रिम निर्दिष्ट करने की आवश्यकता नहीं है। इसके बजाए, वे एक वर्णन घटक प्रक्रिया प्रदान कर सकते हैं जो रन टाइम पर रिटर्न प्रकार निर्धारित करता है। न तो पीटीएफ के लेखक और न ही पीटीएफ के उपयोगकर्ता को वापस आने वाले कॉलम घोषित करने की आवश्यकता है।

एसक्यूएल द्वारा वर्णित पीटीएफ: 2016 अभी तक किसी भी परीक्षण डेटाबेस में उपलब्ध नहीं हैं। 10 इच्छुक पाठक आईएसओ द्वारा जारी "तकनीकी में पॉलिमॉर्फिक टेबल फ़ंक्शन" मुक्त तकनीकी रिपोर्ट का संदर्भ ले सकते हैं। उदाहरण निम्न हैं रिपोर्ट में चर्चा के कुछ:

  • CSVreader, जो संख्या और बदले कॉलम के नाम निर्धारित करने के लिए एक सीवीएस फ़ाइल के हेडर लाइन पढ़ता

  • धुरी (वास्तव में unpivot) मुझे -: है, जो पंक्तियाँ (PHONETYPE, फ़ोननंबर उदाहरण): में स्तंभ समूहों बदल जाता है और नहीं harcoded तार :)

  • TopNplus है, जो विभाजन और एक अतिरिक्त प्रति पंक्ति एन पंक्तियों शेष पंक्तियों

    के योग के साथ के माध्यम से गुजरता

Oracle 18c इस तंत्र लागू करता है। 18c Skip_col Polymorphic Table Function Example Oracle Live SQL और Skip_col Polymorphic Table Function Example

यह उदाहरण दिखाता है नाम/विशिष्ट डेटाप्रकार के आधार पर डेटा को छोड़ने के लिए कैसे:

CREATE PACKAGE skip_col_pkg AS 
    -- OVERLOAD 1: Skip by name 
    FUNCTION skip_col(tab TABLE, col columns) 
      RETURN TABLE PIPELINED ROW POLYMORPHIC USING skip_col_pkg; 

    FUNCTION describe(tab IN OUT dbms_tf.table_t, 
        col  dbms_tf.columns_t) 
      RETURN dbms_tf.describe_t; 

    -- OVERLOAD 2: Skip by type -- 
    FUNCTION skip_col(tab  TABLE, 
        type_name VARCHAR2, 
        flip  VARCHAR2 DEFAULT 'False') 
      RETURN TABLE PIPELINED ROW POLYMORPHIC USING skip_col_pkg; 

    FUNCTION describe(tab  IN OUT dbms_tf.table_t, 
        type_name  VARCHAR2, 
        flip    VARCHAR2 DEFAULT 'False') 
      RETURN dbms_tf.describe_t; 
END skip_col_pkg; 

और शरीर:

CREATE PACKAGE BODY skip_col_pkg AS 

/* OVERLOAD 1: Skip by name 
* NAME: skip_col_pkg.skip_col 
* ALIAS: skip_col_by_name 
* 
* PARAMETERS: 
* tab - The input table 
* col - The name of the columns to drop from the output 
* 
* DESCRIPTION: 
* This PTF removes all the input columns listed in col from the output 
* of the PTF. 
*/ 
    FUNCTION describe(tab IN OUT dbms_tf.table_t, 
        col  dbms_tf.columns_t) 
      RETURN dbms_tf.describe_t 
    AS 
    new_cols dbms_tf.columns_new_t; 
    col_id PLS_INTEGER := 1; 
    BEGIN 
    FOR i IN 1 .. tab.column.count() LOOP 
     FOR j IN 1 .. col.count() LOOP 
     tab.column(i).pass_through := tab.column(i).description.name != col(j); 
     EXIT WHEN NOT tab.column(i).pass_through; 
     END LOOP; 
    END LOOP; 

    RETURN NULL; 
    END; 

/* OVERLOAD 2: Skip by type 
* NAME: skip_col_pkg.skip_col 
* ALIAS: skip_col_by_type 
* 
* PARAMETERS: 
* tab  - Input table 
* type_name - A string representing the type of columns to skip 
* flip  - 'False' [default] => Match columns with given type_name 
*    otherwise   => Ignore columns with given type_name 
* 
* DESCRIPTION: 
* This PTF removes the given type of columns from the given table. 
*/ 

    FUNCTION describe(tab  IN OUT dbms_tf.table_t, 
        type_name  VARCHAR2, 
        flip    VARCHAR2 DEFAULT 'False') 
      RETURN dbms_tf.describe_t 
    AS 
    typ CONSTANT VARCHAR2(1024) := upper(trim(type_name)); 
    BEGIN 
    FOR i IN 1 .. tab.column.count() LOOP 
     tab.column(i).pass_through := 
     CASE upper(substr(flip,1,1)) 
      WHEN 'F' THEN dbms_tf.column_type_name(tab.column(i).description) 
    !=typ 
      ELSE   dbms_tf.column_type_name(tab.column(i).description) 
    =typ 
     END /* case */; 
    END LOOP; 

    RETURN NULL; 
    END; 

END skip_col_pkg; 

और नमूना उपयोग:

-- skip number cols 
SELECT * FROM skip_col_pkg.skip_col(scott.dept, 'number'); 

-- only number cols 
SELECT * FROM skip_col_pkg.skip_col(scott.dept, 'number', flip => 'True') 

-- skip defined columns 
SELECT * 
FROM skip_col_pkg.skip_col(scott.emp, columns(comm, hiredate, mgr)) 
WHERE deptno = 20; 

मैं अत्यधिक उदाहरण पढ़ने के लिए अत्यधिक अनुशंसा करते हैं (स्टैंडअलोन फंक्शन बनाते हैं पैकेज कॉल के बजाय आयनों)।

उदाहरण के लिए आप आसानी से अधिभार छोड़ सकते हैं: कॉलम छोड़ें जो विशिष्ट उपसर्ग/प्रत्यय के साथ प्रारंभ/समाप्त नहीं होता है।

संबंधित मुद्दे