แทนที่จะเข้าไปยุ่งกับคำตอบของมาร์ตินอีกต่อไปฉันจะเพิ่มการค้นพบที่เหลือของฉันPOWER()
ที่นี่
ยึดมั่นในกางเกงของคุณ
คำนำ
ก่อนอื่นฉันขอแสดงเอกสาร A ของ MSDN สำหรับPOWER()
:
วากยสัมพันธ์
POWER ( float_expression , y )
ข้อโต้แย้ง
float_expression
เป็นการแสดงออกของประเภทลอยหรือประเภทที่สามารถแปลงโดยปริยายไปลอย
ประเภทผลตอบแทน
float_expression
เช่นเดียวกับ
คุณอาจสรุปได้จากการอ่านบรรทัดสุดท้ายที่POWER()
เป็นประเภทการส่งคืนFLOAT
แต่อ่านอีกครั้ง float_expression
คือ "ประเภทลอยหรือประเภทที่สามารถแปลงเป็นลอย" โดยปริยาย ดังนั้นแม้จะมีชื่อของมันfloat_expression
จริงอาจจะFLOAT
เป็นหรือDECIMAL
INT
เนื่องจากเอาต์พุตของPOWER()
เหมือนกันกับของfloat_expression
มันก็อาจเป็นหนึ่งในประเภทเหล่านั้น
ดังนั้นเราจึงมีฟังก์ชันสเกลาร์พร้อมชนิดส่งคืนที่ขึ้นอยู่กับอินพุต มันอาจจะเป็น?
ข้อสังเกต
ผมนำเสนอให้คุณแสดง B, แสดงให้เห็นถึงการทดสอบที่ปลดเปลื้องการส่งออกไปยังชนิดข้อมูลที่แตกต่างกันขึ้นอยู่กับปัจจัยการผลิตPOWER()
SELECT
POWER(10, 3) AS int
, POWER(1000000000000, 3) AS numeric0 -- one trillion
, POWER(10.0, 3) AS numeric1
, POWER(10.12305, 3) AS numeric5
, POWER(1e1, 3) AS float
INTO power_test;
EXECUTE sp_help power_test;
DROP TABLE power_test;
ผลลัพธ์ที่เกี่ยวข้องคือ:
Column_name Type Length Prec Scale
-------------------------------------------------
int int 4 10 0
numeric0 numeric 17 38 0
numeric1 numeric 17 38 1
numeric5 numeric 17 38 5
float float 8 53 NULL
สิ่งที่ดูเหมือนจะเกิดขึ้นคือPOWER()
ปลดเปลื้องลงในประเภทที่เล็กที่สุดที่เหมาะกับมันไม่รวมfloat_expression
BIGINT
ดังนั้นSELECT POWER(10.0, 38);
ด้วยข้อผิดพลาดล้นเพราะ10.0
ได้รับการโยนไปNUMERIC(38, 1)
ซึ่งไม่ใหญ่พอที่จะถือผล 10 38 นั่นเป็นเพราะ 10 38ขยายตัวให้เป็น 39 หลักก่อนจุดทศนิยมในขณะที่NUMERIC(38, 1)
สามารถเก็บ 37 หลักก่อนทศนิยมบวกหนึ่งหลัง ดังนั้นค่าสูงสุดNUMERIC(38, 1)
สามารถถือได้คือ 10 37 - 0.1
ด้วยความเข้าใจนี้ฉันสามารถปรุงความล้มเหลวได้อีกด้วย
SELECT POWER(1000000000, 3); -- one billion
หนึ่งพันล้านบาท (เมื่อเทียบกับหนึ่งล้านล้านจากตัวอย่างแรกซึ่งจะโยนไปNUMERIC(38, 0)
) INT
เป็นพอเพียงเพื่อให้พอดีกับขนาดเล็กใน หนึ่งพันล้านยกกำลังสามอย่างไรก็ตามใหญ่เกินไปINT
ดังนั้นข้อผิดพลาดล้น
ฟังก์ชั่นอื่น ๆ อีกหลายตัวแสดงพฤติกรรมที่คล้ายกันโดยที่ประเภทเอาท์พุทขึ้นอยู่กับอินพุต:
ข้อสรุป
SELECT POWER(1e1, precision)...
ในกรณีนี้โดยเฉพาะอย่างยิ่งการแก้ปัญหาคือการใช้งาน สิ่งนี้จะใช้ได้กับพื้นที่ที่มีความเป็นไปได้ทั้งหมดตั้งแต่1e1
เข้าสู่พื้นที่FLOAT
ซึ่งสามารถเก็บจำนวนมากได้อย่างน่าขัน
เนื่องจากฟังก์ชั่นเหล่านี้เป็นเรื่องธรรมดาจึงเป็นเรื่องสำคัญที่จะต้องเข้าใจว่าผลลัพธ์ของคุณอาจถูกปัดเศษหรืออาจทำให้เกิดข้อผิดพลาดมากเกินไปเนื่องจากพฤติกรรมของพวกเขา หากคุณคาดหวังหรือพึ่งพาประเภทข้อมูลเฉพาะสำหรับผลลัพธ์ของคุณให้ส่งสัญญาณที่เกี่ยวข้องตามความจำเป็นอย่างชัดเจน
ดังนั้นเด็ก ๆ เมื่อคุณรู้สิ่งนี้คุณอาจออกไปข้างนอกและประสบความสำเร็จ