ส่งคืนเฉพาะแถวที่มีฟิลด์ว่างใช่ไหม

ฉันมีตารางที่ช่องใดช่องหนึ่งสามารถเว้นว่างได้ ฉันกำลังพยายามส่งคืนเฉพาะแถวเหล่านี้โดยที่ฟิลด์นี้ว่างเปล่า แต่ฉันได้รับข้อผิดพลาดอยู่เรื่อย ๆ เพียงแค่ทำ WHERE field = "" ... WHERE field = '' ... WHERE field = null

มีความคิดใดที่ฉันขาดหายไป?


person Mik0r    schedule 10.01.2011    source แหล่งที่มา
comment
คุณกำลังใส่อะไรใน ...?   -  person Mark Peters    schedule 11.01.2011
comment
ฉันคิดว่านี่แสดงให้เห็นถึงสามข้อความที่เป็นไปได้ Where   -  person Fionnuala    schedule 11.01.2011


คำตอบ (5)


ใน SQL ฟิลด์ว่างทั้งหมดเรียกว่า NULL สำหรับการค้นหา NULL คุณไม่ได้ใช้เท่ากับ (=) แต่ใช้โอเปอเรเตอร์พิเศษ IS NULL:

 SELECT * FROM table WHERE field IS NULL

Access ช่วยให้คุณไม่มีฟิลด์ว่างเป็น NULL หากคุณอนุญาตให้ใช้สตริงว่าง นี่เป็นความคิดที่ไม่ดี เนื่องจากจะทำให้แยกแยะภาพระหว่างค่า NULL และสตริงที่มีความยาว 0 ได้ยาก ดังนั้นฉันขอแนะนำให้คุณอย่าอนุญาตใน ฐานข้อมูล

person Larry Lustig    schedule 10.01.2011
comment
สามารถใช้สตริงที่มีการเว้นวรรคและมีความยาวเป็นศูนย์ได้ ดังนั้นเพื่อให้ครอบคลุมฐานทั้งหมด คุณสามารถใช้ Trim(field & )= ได้ - person Fionnuala; 11.01.2011
comment
ฉันจะยอมรับสตริงที่มีความยาว 0 ว่าว่างเปล่า แต่โดยส่วนตัวแล้วฉันจะไม่ถือว่าสตริงที่มีการเว้นวรรคว่างเปล่า ไม่ว่าในกรณีใด จากคำถามนี้ ฉันค่อนข้างแน่ใจว่าปัญหา OPs ไม่ได้ระบุสตริงว่างประเภทต่างๆ แต่ไม่ทราบตัวดำเนินการ IS NULL - person Larry Lustig; 11.01.2011

SELECT * 
  FROM MyTable 
 WHERE IIF(MyField = ' ', NULL, MyField) IS NULL;

อัปเดต: นี่คือการสาธิตวิธีการทำงานของ "ANSI padding" ใน Access Database Engine (ACE, Jet หรืออะไรก็ตาม) ซึ่งดูเหมือนว่าจะจำเป็น (แน่นอนว่าผลิตภัณฑ์ SQL ทุกตัวในพื้นที่ทำงานในลักษณะนี้ ... ?): เพียงวาง ลงในโมดูล VBA ใด ๆ (Access, Excel, Word ฯลฯ ) หรือ VB6 แล้วเรียกใช้ (ไม่ต้องมีการอ้างอิง ฯลฯ ): หากเป็นจริงที่ช่องว่างเดียวเท่ากับสตริงที่มีความยาวเป็นศูนย์ (ZLS) หรือจำนวน 'ไม่ได้กำหนด' ของ ช่องว่างแล้วคุณจะเห็นรายการ Ys:

Sub Fundamentals()

  On Error Resume Next
  Kill Environ$("temp") & "\DropMe.mdb"
  On Error GoTo 0

  Dim cat
  Set cat = CreateObject("ADOX.Catalog")
  With cat
    .Create _
        "Provider=Microsoft.Jet.OLEDB.4.0;" & _
        "Data Source=" & _
        Environ$("temp") & "\DropMe.mdb"
    With .ActiveConnection

      Dim SQL As String
      SQL = _
      "SELECT IIF(SPACE(0) = SPACE(1), 'Y', 'N')," & vbCr & _
      "       IIF(SPACE(1) = SPACE(1), 'Y', 'N')," & vbCr & _
      "       IIF(SPACE(2) = SPACE(1), 'Y', 'N')," & vbCr & _
      "       IIF(SPACE(3) = SPACE(1), 'Y', 'N')," & vbCr & _
      "       IIF(SPACE(4) = SPACE(1), 'Y', 'N')," & vbCr & _
      "       IIF(SPACE(5) = SPACE(1), 'Y', 'N')," & vbCr & _
      "       IIF(SPACE(55) = SPACE(1), 'Y', 'N')," & vbCr & _
      "       IIF(SPACE(99) = SPACE(1), 'Y', 'N')," & vbCr & _
      "       IIF(SPACE(255) = SPACE(1), 'Y', 'N')," & vbCr & _
      "       IIF(SPACE(4321) = SPACE(1), 'Y', 'N')," & vbCr & _
      "       IIF(SPACE(54321) = SPACE(1), 'Y', 'N')," & vbCr & _
      "       IIF(SPACE(654321) = SPACE(1), 'Y', 'N');"

      .Execute SQL

      Dim rs
      Set rs = .Execute(SQL)
      MsgBox rs.GetString(, , vbCr)
    End With
    Set .ActiveConnection = Nothing
  End With
End Sub

อัปเดต 2:

แน่นอนว่า Jet/ACE ไม่ได้แพดฟิลด์ให้มีความยาวคงที่!

ไม่ถูกต้อง. ฐานข้อมูล Access มีประเภทข้อมูลข้อความที่มีความกว้างคงที่ซึ่งโดยทั่วไปเรียกว่า NCHAR(n) (แม้ว่าจะใช้คำพ้องความหมายอื่นก็ตาม) ซึ่งจะขยายค่าคอลัมน์ให้มีความยาวคงที่...

NCHAR (10) ในตัวออกแบบตาราง Access เป็นประเภทข้อมูลใด

ฉันทำไม่ได้มันจะแสดงในสิ่งที่ออกแบบตารางอย่างถูกต้อง Access UI ยังคงล้าหลังเทคโนโลยี Jet 4.0 มีการละเว้นหลายประการ ฉันยังไม่ได้ติดตั้ง Access ในขณะนี้ - อาจมีคนสามารถเรียกใช้โค้ดต่อไปนี้ เปิด .mdb ใน Access UI แล้วบอกเรา...

Sub AccessNChar()

  On Error Resume Next
  Kill Environ$("temp") & "\DropMe.mdb"
  On Error GoTo 0

  Dim cat
  Set cat = CreateObject("ADOX.Catalog")
  With cat
    .Create _
        "Provider=Microsoft.Jet.OLEDB.4.0;" & _
        "Data Source=" & _
        Environ$("temp") & "\DropMe.mdb"
    With .ActiveConnection

      Dim Sql As String

      Sql = "CREATE TABLE TestNChar (col1 NCHAR(10));"
      .Execute Sql

      Sql = "INSERT INTO TestNChar (col1) VALUES (SPACE(1));"
      .Execute Sql

      Sql = "SELECT LEN(col1) FROM TestNChar;"

      Dim rs
      Set rs = .Execute(Sql)

      MsgBox rs.GetString
    End With
    Set .ActiveConnection = Nothing
  End With
End Sub
person onedaywhen    schedule 11.01.2011
comment
@Remou: มันจะตรวจสอบ ZLS หรือช่องว่างที่ไม่ได้กำหนดไว้อย่างแน่นอน - person onedaywhen; 11.01.2011
comment
ฮะ? ยังไง? สำหรับฉันดูเหมือนว่ากำลังตรวจสอบช่องว่างเดียวและจะส่งคืน ZLS หรือช่องว่างจำนวนอื่น ๆ หากเงื่อนไขเริ่มต้น IIf() ไม่ตรงกัน และมันจะไม่ใช้ดัชนี ดังนั้นสำหรับฉันแล้วดูเหมือนว่าเป็นความคิดที่แย่มาก - person David-W-Fenton; 12.01.2011
comment
@ Davide-W-Fenton และ @Remou: คุณทั้งคู่มีป้าย MS-Access ที่นี่ใน SO นี่เป็นสิ่งพื้นฐาน! ลักษณะการทำงานมาตรฐานเมื่อเปรียบเทียบสองสายเพื่อความเท่าเทียมกันคือแผ่นปิดท้ายจะสั้นกว่าและมีอักขระเว้นวรรค แม้ว่าคุณจะไม่รู้เรื่องนี้ (น่าตกตะลึง!) หรือลืมไปชั่วขณะ แต่ก็เป็นเรื่องง่ายสำหรับคุณที่จะทดสอบ ในชุมชนเช่นนี้ ฉันคาดหวังให้คุณทดสอบโค้ดของฉัน การตรวจสอบโดยผู้ทรงคุณวุฒิ และอื่นๆ อีกมากมาย แต่ฉันคิดว่าฉันจะต้องโพสต์หลักฐานของฉันว่าเป็นโค้ดที่ใช้งานง่ายมาก (สมมติว่าคุณมีความสุภาพที่จะใส่ใจในการเรียกใช้!) - person onedaywhen; 12.01.2011
comment
ฉันไม่ได้ตระหนักถึงเรื่องนี้และพบว่ามันไม่มีประโยชน์ ฉันไม่เคยเจอมันเลยเพราะฉันไม่อนุญาตให้มีช่องว่างในตารางข้อมูลของฉัน หากฐานข้อมูลทั้งหมดทำงานในลักษณะนี้ ฉันจะบอกว่าฐานข้อมูลเหล่านั้นผิด เนื่องจากไม่มีวิธีใช้ดัชนีในการค้นหาฟิลด์ที่มีช่องว่างเพียงช่องเดียว และแน่นอน หากคุณอนุญาตให้มีการจัดเก็บช่องว่างในช่องข้อมูลของคุณ มันจะต้องมีความหมายบางอย่าง และช่องว่างหนึ่งจะต้องหมายถึงบางสิ่งที่แตกต่างจากสอง เรียกฉันว่าคนงี่เง่าก็ได้ถ้าคุณต้องการ แต่ดูเหมือนว่าจะเป็นสิ่งประดิษฐ์ของการจัดเก็บข้อมูลสไตล์ dBase แบบโบราณ แน่นอนว่า Jet/ACE ไม่ได้แพดฟิลด์ให้มีความยาวคงที่! - person David-W-Fenton; 19.01.2011
comment
@ David-W-Fenton: เรียกฉันว่าคนงี่เง่าถ้าคุณต้องการ แต่ดูเหมือนว่าจะเป็นสิ่งประดิษฐ์ของการจัดเก็บข้อมูลสไตล์ dBase โบราณ - มันเป็นสิ่งประดิษฐ์ของ SQL-92 ซึ่งตัวมันเองยาวนิดหน่อย ฉันจะไม่เรียกคุณว่าคนงี่เง่า แต่จะชี้ให้เห็นว่าการยอมรับความเป็นจริงใหม่เป็นสิ่งที่คุณดูเหมือนจะมีปัญหา - person onedaywhen; 19.01.2011
comment
@ David-W-Fenton: ฉันไม่อนุญาตให้จัดเก็บช่องว่างในตารางข้อมูลของฉัน - ฉันคิดว่าคุณไม่อนุญาตช่องว่างในทุกสถานการณ์เช่น ช่องว่างระหว่างสองคำก็โอเคใช่ไหม? :) ฉันมักจะเพิ่มข้อจำกัด CHECK ให้กับคอลัมน์ข้อความทั้งหมดเพื่อไม่อนุญาต: 1) ช่องว่างที่มีความยาวเป็นศูนย์ 2) ช่องว่างนำหน้า 3) ช่องว่างต่อท้าย 4) ช่องว่างสองช่องติดต่อกัน - person onedaywhen; 19.01.2011
comment
NCHAR (10) ในตัวออกแบบตาราง Access เป็นประเภทข้อมูลใด - person David-W-Fenton; 21.01.2011
comment
@ David-W-Fenton: ใช่ คุณจะต้องใช้ SQL DDL ในโหมดแบบสอบถาม ANSI-92 เพื่อสร้างวัตถุฐานข้อมูลดังกล่าว คุณอาจต้อง OLE DB เพื่อตรวจจับการมีอยู่และแสดงคุณสมบัติของพวกเขา อย่างไรก็ตาม นี่ไม่ได้หมายความว่าไม่มีอยู่จริง และ IMO ผู้เชี่ยวชาญด้านการเข้าถึงที่เคารพตนเองควรจะสามารถอธิบายปัญหาที่พวกเขาออกแบบมาเพื่อแก้ไขได้เป็นอย่างน้อย - person onedaywhen; 21.01.2011
comment
@ David-W-Fenton: คำตอบนี้อัปเดตเพิ่มเติมด้วยโค้ดเพื่อสร้าง .mdb ใหม่พร้อมตารางที่ประกอบด้วยคอลัมน์ NCHAR(10) บางทีคุณอาจเรียกใช้โค้ด เปิด .mdb ใน Access แล้วบอกเราว่าคุณเห็นอะไร ทีไอเอ. - person onedaywhen; 21.01.2011
comment
ฉันเป็นนักพัฒนา Access ไม่ใช่นักพัฒนา Jet/ACE ประเด็นของฉันในการถามคำถามคือการยกประเด็นว่าทำไม Jet/ACE จึงรองรับ NCHAR (10) ฉันเดาว่ามันเข้ากันได้กับมาตรฐานภายนอกที่ไม่มีความหมายใด ๆ สำหรับนักพัฒนา Access ฉันคิดไม่ออกว่าทำไมฉันถึงต้องการมัน คุณช่วยหาเหตุผลว่าทำไมฉันถึงควรสนใจที่จะเรียนรู้เกี่ยวกับฟีเจอร์ที่ฉันไม่จำเป็นต้องใช้ ซึ่งเป็นฟีเจอร์ที่นำมาใช้กับกลไกฐานข้อมูลเพื่อให้เข้ากันได้กับสิ่งต่าง ๆ ที่อยู่นอกสภาพแวดล้อมการทำงานของฉันหรือไม่ - person David-W-Fenton; 22.01.2011
comment
@ David-W-Fenton: ทำไม Jet/ACE รองรับ NCHAR(10) - เป็นประเภทข้อมูลความกว้างคงที่สำหรับข้อมูลที่มีความกว้างคงที่ ซึ่งเป็นเรื่องปกติมาก ตัวระบุมาตรฐานอุตสาหกรรมส่วนใหญ่ที่ฉันพบมีความกว้างคงที่ เช่น จนถึงทุกวันนี้ ฉันใช้รหัสประเทศ ISO 3166-1 alpha-3, รหัสสกุลเงิน ISO 4217 และรหัส SIC อุตสาหกรรม - person onedaywhen; 24.01.2011
comment
@ David-W-Fenton: คุณช่วยหาเหตุผลว่าทำไมฉันถึงควรเรียนรู้เกี่ยวกับคุณสมบัติที่ฉันไม่จำเป็นต้องใช้ - ฉันบอกว่าคุณควรมีความรู้เกี่ยวกับปัญหาที่พวกเขาออกแบบมาเพื่อแก้ไขเช่น เพื่อที่คุณจะได้ไม่เกิดข้อบกพร่องแบบเดียวกันซ้ำกับผลิตภัณฑ์ของลูกค้า คุณมีเหตุผลอะไรในการมีความรู้เพียงชุดย่อยของประเภทข้อมูลของภาษา - person onedaywhen; 24.01.2011
comment
ฉันเคยใช้ Jet/ACE ผ่าน Access เท่านั้น และเนื่องจาก Access ไม่ได้เปิดเผยประเภทข้อมูลเหล่านี้ว่าใช้งานได้โดยตรง ฉันจึงไม่ใช้มัน ฉันไม่เข้าใจจริงๆ ว่าทำไมรูปแบบข้อมูลที่มีความยาวผันแปรได้จึงได้ประโยชน์จากการมีตัวเลือกความยาวคงที่ แต่บางทีฉันอาจไม่เข้าใจด้วยซ้ำว่ามันหมายถึงอะไร (ฉันถือว่าความกว้างคงที่หมายถึงความกว้างคงที่ บุด้วยช่องว่าง a la xBase c. 1988) - person David-W-Fenton; 25.01.2011

คุณหมายถึงอะไรโดยข้อผิดพลาด?

แต่ถ้าคุณต้องการรับเฉพาะแถวที่มีฟิลด์ว่าง ให้ลองทำดังนี้:

SELECT * FROM MyTable WHERE LTRIM(RTRIM(ISNULL(MyField, ''))) = ''
person Stephen Wrighton    schedule 10.01.2011
comment
สำหรับการเข้าถึง คุณจะต้องใช้ Nz แทนที่จะเป็น ISNULL(MyField, '') IsNull ไม่ใช้มากกว่าหนึ่งอาร์กิวเมนต์ - person Fionnuala; 11.01.2011
comment
นั่นเป็นเรื่องจริง แน่นอน ฉันไม่ได้ใช้การเข้าถึง ดังนั้นฉันจึงมักจะลืมข้อมูลเฉพาะเกี่ยวกับวิธีที่ Access ทรมาน SQL - person Stephen Wrighton; 11.01.2011
comment
กลไกฐานข้อมูลทั้งหมดมีรูปแบบในภาษา SQL ที่แตกต่างกัน -1 สำหรับการโพสต์คำตอบที่ไม่ใช่การเข้าถึง - person David-W-Fenton; 12.01.2011
comment
ทางออกที่ดี โดยการประเมินค่า NULL ล่วงหน้า เปลี่ยนเป็นสตริงว่าง จากนั้นตัดทั้งสองด้านรับประกันว่าเขาจะได้รับสตริงอักขระสำหรับการทดสอบ Final = '' - person DRapp; 10.03.2011

คำถามของคุณมี WHERE 3 ข้อหรือไม่ หากเป็นเช่นนั้น ให้เปลี่ยนสองตัวที่สองเป็น OR

person Parris Varney    schedule 10.01.2011

ใช่ ฉันกำลังเผชิญกับสิ่งเดียวกัน แต่ในที่สุดฉันก็ลองใช้แบบสอบถาม mySQL ต่อไปนี้ มันใช้งานได้และช่วยฉันไว้

  SELECT * from your_table_name WHERE field_name IS NULL;

ดำเนินการต่อด้วยแบบสอบถามนี้จะเลือกเฉพาะแถวที่ว่างเปล่า

person Deepak N    schedule 25.11.2017