แทนที่จะเข้าไปยุ่งกับคำตอบของมาร์ตินอีกต่อไปฉันจะเพิ่มการค้นพบที่เหลือของฉัน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_expressionBIGINT
ดังนั้น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ซึ่งสามารถเก็บจำนวนมากได้อย่างน่าขัน
เนื่องจากฟังก์ชั่นเหล่านี้เป็นเรื่องธรรมดาจึงเป็นเรื่องสำคัญที่จะต้องเข้าใจว่าผลลัพธ์ของคุณอาจถูกปัดเศษหรืออาจทำให้เกิดข้อผิดพลาดมากเกินไปเนื่องจากพฤติกรรมของพวกเขา หากคุณคาดหวังหรือพึ่งพาประเภทข้อมูลเฉพาะสำหรับผลลัพธ์ของคุณให้ส่งสัญญาณที่เกี่ยวข้องตามความจำเป็นอย่างชัดเจน
ดังนั้นเด็ก ๆ เมื่อคุณรู้สิ่งนี้คุณอาจออกไปข้างนอกและประสบความสำเร็จ