问题描述
我可以从oracle表中创建发票的序列号
表:
ID YEAR LAST_VALUE
ABC 2020 900
DEF 2020 500
GHI 2020 250
通过这个表格,我想创建一个像这样的列表
ABC2020001
ABC2020002
.
.
ABC2020900
DEF2020001
DEF2020002
.
.
DEF2020500
GHI2020001
GHI2020002
.
.
GHI2020250
解决方法
一个选项使用递归查询来生成数字序列:
with cte (id,yr,last_val,val) as (
select id,1 from mytable
union all
select id,val + 1 from cte where val < last_val
)
select id || yr || to_char(val,'fm0000') serial_number from cte
,
您需要的只是横向的。就这样。每当您在任何论坛上发布问题时,总是要提及您的Oracle版本(以下解决方案至少需要12分)。以下是您需要的。顺便说一句,last_value是一个解析函数,不能使用相同的名称作为列名。因此,我使用了lastvalue。
select * from data,lateral
(
select id||year||to_char(level,'fm000') as new_id
from dual
connect by level <= lastvalue
)
,
另一种选择,
我们可以通过使用connect by
并通过强制转换键入sys.odcinumberlist
来使用起点和终点来生成序列来做到这一点。
with data
as
(
select 'ABC' id,2020 year,900 lastvalue,1 firstvalue
from dual
union all
select 'DEF',2020,500,1 from dual
union all
select 'GHI',250,1 from dual
)
select id||year||
lpad((firstvalue +
series.column_value - 1),length(lastvalue),'0'
)invoicenumber
from data,table(cast(multiset
(select level
from dual
connect by level <= lastvalue-firstvalue + 1)
as sys.odcinumberlist)) series
,
这假定您的Oracle数据库中有一个名为SerialNumbers
的表,该表具有2个字段,SerialNumber
是某种字符串类型,并用作Oracle对布尔值的解释。
我们用您的序列号填充Datatable
,然后将其发送给Oracle。
Private ConStr As String = "Your connection string"
Private Sub OPCode()
Dim dt As New DataTable
dt.Columns.Add("SerialNumber",GetType(String))
dt.Columns.Add("Used",GetType(Boolean))
Dim letters = {"ABC","DEF","GHI","HIJ","KLM","NOP","QRS","TUV","WXY"}
For Each LetterGroup In letters
For i = 1 To 900
Dim sn = LetterGroup & i.ToString.PadRight(3,"0"c)
dt.Rows.Add(sn,False)
Next
Next
Using cn As New OracleConnection(ConStr),da As New OracleDataAdapter("Select SerialNumber,Used From SerialNumbers;",cn)
Dim cb As New OracleCommandBuilder(da)
da.Update(dt)
End Using
End Sub
当您需要新的序列号...
Private Function GetNextSerialNumber() As String
Dim RetVal As String
Using cn As New OracleConnection(ConStr),cmd As New OracleCommand("Select Top 1 SerialNumber From SerialNumbers Where Used = False Order By SerialNumber;",cn)
cn.Open()
RetVal = CStr(cmd.ExecuteScalar)
cmd.CommandText = "Update SerialNumbers Set Used = True Where SerialNumber = @SN;"
cmd.Parameters.Add("@SN",OracleDbType.Varchar2).Value = RetVal
cmd.ExecuteNonQuery()
End Using
Return RetVal
End Function