MSSQL 如何实现 Excel中的 BathText() 函数功能

问题描述

要在sqlserve 中使用一个自定义函数来实现泰铢大写的输出,自己写了个自定义函数,但因不理解泰铢语法规则,总是会出错。

问题出现的环境背景及自己尝试过哪些方法

尝试过使用sql自定函数一个个数值进行处理,还出出现问题。
发现js有实现这个功能的函数,单因sql无数组无法实现修改:
https://github.com/jojoee/bah...

相关代码

// 请把代码文本粘贴到下方(请勿用图片代替代码)

/*
step:
1. validate
2. sanitize
3. split
4. proceed
5. grammar
6. combine
*/

const defaultResult = 'ศูนย์บาทถ้วน'
const singleUnitStrs = [
  '',
  'หนึ่ง',
  'สอง',
  'สาม',
  'สี่',
  'ห้า',
  'หก',
  'เจ็ด',
  'แปด',
  'เก้า'
]
const placeNameStrs = [
  '',
  'สิบ',
  'ร้อย',
  'พัน',
  'หมื่น',
  'แสน',
  'ล้าน'
]

/**
 * @param {number[]} nums
 * @returns {string}
 */
function num2Word (nums) {
  let result = ''
  const len = nums.length
  const maxLen = 7

  if (len > maxLen) {
    // more than million
    const overflowIndex = len - maxLen + 1
    const overflowNums = nums.slice(0, overflowIndex)
    const remainingNumbs = nums.slice(overflowIndex)
    return num2Word(overflowNums) + 'ล้าน' + num2Word(remainingNumbs)
  } else {
    for (let i = 0; i < len; i++) {
      const digit = nums[i]
      if (digit > 0) {
        result += singleUnitStrs[digit] + placeNameStrs[len - i - 1]
      }
    }
  }

  return result
}

/**
 * @param {string} str
 * @returns {string}
 */
function grammarFix (str) {
  let result = str

  // "สิบ"
  result = result.replace('หนึ่งสิบ', 'สิบ')
  // "ยี่สิบ"
  result = result.replace('สองสิบ', 'ยี่สิบ')
  // "เอ็ด"
  const neungLen = 5
  if (result.length > neungLen &&
    result.length - result.lastIndexOf('หนึ่ง') === neungLen) {
    result = result.substr(0, result.length - neungLen) + 'เอ็ด'
  }

  return result
}

/**
 * Combine baht and satang
 * and also adding unit
 *
 * @param {string} baht
 * @param {string} satang
 * @returns {string}
 */
function combine (baht, satang) {
  let result = ''

  if (baht === '' && satang === '') {
    result = defaultResult
  } else if (baht !== '' && satang === '') {
    result = baht + 'บาท' + 'ถ้วน'
  } else if (baht === '' && satang !== '') {
    result = satang + 'สตางค์'
  } else {
    result = baht + 'บาท' + satang + 'สตางค์'
  }

  return result
}

/**
 * Change number to Thai pronunciation string
 *
 * @param {number} num
 * @returns {string}
 */
function bahttext (num) {
  let result = defaultResult

  // 1. validate: invalid number
  if (isNaN(num)) return result
  // 1. validate: more than
  if (num >= Number.MAX_SAFE_INTEGER) return result

  // 2. sanitize: ????

  // 3. split: baht and satang
  // e.g. 432.21 >> 432, 21
  // @todo optimize
  /** @type {string} */
  const bahtStr = Math.floor(num).toString()
  /** @type {string} */
  const satangStr = Math.round(num % 1 * 100).toString()

  // 3. split: convert number array
  // @todo optimize it
  /** @type {number[]} */
  const bahtArr = Array.from(bahtStr).map(Number)
  /** @type {number[]} */
  const satangArr = Array.from(satangStr).map(Number)

  // 4. proceed
  let baht = num2Word(bahtArr)
  let satang = num2Word(satangArr)

  // 5. grammar
  baht = grammarFix(baht)
  satang = grammarFix(satang)

  // 6. combine
  result = combine(baht, satang)

  return result
}

if (typeof module !== 'undefined' &&
  module.exports != null) {
  module.exports = bahttext
}

---js

你期待的结果是什么?实际看到的错误信息又是什么?

哪位大神是否可提供相关的思路或者参考材料?
能实现在sql中定义一个自定义函数,输出泰文大写金额即可,不一定参照上面js的代码来写。

谢谢。

阅读 1.9k
1 个回答
✓ 已被采纳新手上路,请多包涵

问题已解决。
此前总是想着在mssql 中实现数组,所以没实现。
后来直接将金额转为字符,数组循环部分,sql中使用条件语句来针对字符进行处理即可实现。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题