How to insert split-ed amount into a table without using loop? - sql

I need to split an amount into multiple part and insert into an table called installment, how can i implement it without using loop?
declare #installment as table (installment_index int identity(1,1),
amount money,
due_date datetime)
declare #total_amount money
declare #number_of_installment int
declare #amount money
declare #i int
declare #date datetime
set #date = getdate()
set #number_of_installment = 20
set #total_amount = 5001.00
set #amount = #total_amount / #number_of_installment
set #i= 1
while #i <= #number_of_installment
begin
insert into #installment
(amount,due_date) values (#amount, dateadd(month,#i,#date))
set #i = #i + 1
end

This would replace while loop:
;with numbers as (
select 1 number
union all
select number + 1
from numbers
where number < #number_of_installment
)
insert into #installment (amount,due_date)
select #amount, dateadd(month,number,#date)
from numbers
option (maxrecursion 0)
CTE numbers returns table of numbers from 1 to #number_of_installment
insert uses this table to insert #number_of_installment records to #installment.
EDIT:
I must mention that, according to this article, nothing beats auxiliary table of numbers/dates for similar purposes.

Related

SQL server transfer column from one table to another

I am trying to transfer data from a column from one table to another, both columns are with unique identifiers and when i transfer the data it is copying the column after the end of the data of the second table. After the end of the other column of the second table (I am inserting first random integers in the first column and then I want to copy the information from another table in the same database and it is starting after the 135th row (I add 135 rows with random ints)). First table name : carBrand and column name model_id - second table name Cars11, model_idss - or whatever is the name...
THE QUESTION IS WHY is it inputting the iformation after the first input - example - i am inputting 135 random ints and after that i am trying to copy the information from the other table and when i am pasting it, the information is pasted after the 136th to the 270th sign
My query is looking like this for the new table
DECLARE #Min_Value AS int
SET #Min_Value= 15000
DECLARE #Max_Value AS int
SET #Max_Value = 1000000
DECLARE #n AS int
SET #n = 135
BEGIN TRANSACTION
DECLARE #uid uniqueidentifier
SET #uid = NEWID()
DECLARE #i AS int
SET #i = 1
WHILE #i <= #n BEGIN INSERT INTO Cars11([Model_prices]) VALUES(FLOOR(RAND(CHECKSUM(#uid))*(#Max_Value - #Min_Value +1) + #Min_Value)) SET #i += 1 SET #uid = NEWID() END COMMIT TRANSACTION
INSERT INTO Cars11(model_idss)
SELECT model_id
FROM carBrand
WHERE model_id <= 135;
It would be easier to parse your query if you used the code sample block (ctrl-k)
You need to do an update instead of insert for the second insert into Cars11.
Update changes already existing records, Insert creates new records.
Something like this:
DECLARE #Min_Value AS int
SET
#Min_Value = 15000
DECLARE #Max_Value AS int
SET
#Max_Value = 1000000
DECLARE #n AS int
SET
#n = 135
BEGIN TRANSACTION
DECLARE #uid uniqueidentifier
SET
#uid = NEWID()
DECLARE #i AS int
SET
#i = 1 WHILE #i <= #n
BEGIN
INSERT INTO
Cars11([Model_prices])
VALUES
(
FLOOR(
RAND(CHECKSUM(#uid)) *(#Max_Value - #Min_Value + 1) + #Min_Value
)
)
SET
#i + = 1
SET
#uid = NEWID()
END
COMMIT TRANSACTION
UPDATE Cars11
Set model_idss = (Select model_id FROM carBrand WHERE Cars11.model_idss = carBrand.model_id and carBrand.model_id <= 135));
Here are some other options for updating a column based on a query result

sql accumulating decimals at the end

I need help with a simple query for dividing a value to equal numbers. But I also want to avoid decimals values to accumulate them all to the final value.This is achievable by query below, however if I choose different datatype such as MONEY or NUMERIC for #amt, it gets tricky. Can anyone do what I did below with MONEY or NUMERIC datatype?
DECLARE #tbl TABLE (id TINYINT, princ NUMERIC (14,2))
DECLARE #counter INT = 1
DECLARE #term TINYINT = 12
DECLARE #amt INT = 50000
DECLARE #decimals INT = #amt-((#amt/#term)*#term)
WHILE #counter <= #term
BEGIN
INSERT INTO #tbl (id,princ)
SELECT #counter, #amt/#term
SET #counter = #counter + 1
UPDATE #tbl SET princ = princ+#decimals WHERE id = #term
END
SELECT * FROM #tbl
<Do what you need to do you populate the table, excluding the last row>
INSERT INTO
#tbl (
id,
princ
)
SELECT
MAX(id) + 1,
#amt - SUM(princ)
FROM
#tbl
Or, perhaps, with a CTE...
WITH
recursive_distribution AS
(
SELECT 0 AS id, CAST(#amt / #term AS INT) AS princ
UNION ALL
SELECT id + 1, princ
FROM recursive_distribution
WHERE id < #term - 1
UNION ALL
SELECT 1, #amt - (princ * (#term-1))
FROM recursive_distribution
WHERE id = #term - 1
)
INSERT INTO
#tbl (id, princ)
SELECT
id, princ
FROM
recursive_distribution
WHERE
id > 0
OPTION
(MAXRECURSION 0) -- Only needed if #term >= 100
(Starting at 0, then excluding row 0 means this can cope with #term = 1)

How to pass certain values from a table to a stored procedure

This is my problem. I have a table tbl_archivos with values like this:
Id desc namerc
---------------------------
1 arch1 RC201721091701
2 arch2 RC201724091701
I have to pass all the values of the column namerc in my table (above) to a stored procedure like parameter.
Like this :
sp_runproceess_billing 'RC201721091701'
and then the another value RC201724091701.
I am not allowed to use a cursor!
Please help me with this issue.
Thank you
try this solution
DECLARE #t AS TABLE(id INT PRIMARY KEY IDENTITY, namerc VARCHAR(50))
INSERT INTO #t
SELECT DISTINCT namerc FROM tbl_archivos
ORDER BY tbl_archivos
DECLARE #index INT = 1
DECLARE #max INT = (SELECT COUNT(*) FROM #t)
DECLARE #current_namerc VARCHAR(50)
WHILE #index <= #max
BEGIN
SELECT #current_namerc = namerc FROM #t WHERE id = #index
EXEC sp_runproceess_billing #current_namerc
SET #index = #index + 1
END

sql use while loop to fetch values and run query on them

I have long query which is ran based on two value parameters (contcode, datime).
I am using this while loop to fetch these values in order from another table, run the query and insert the result into a final table:
DECLARE #r TABLE (id int IDENTITY (1,1),lnr char (9), pday datetime)
INSERT INTO #r (lnr, pday)
SELECT TOP 1 lnr, pday FROM memrepay
DECLARE #counter int SET #counter = 1
DECLARE #contcode char (9)
DECLARE #datime datetime
WHILE #counter <= (SELECT COUNT(*) FROM #r)
BEGIN
--long query
END
SET #counter = #counter + 1
END
SELECT * FROM #finaltable
However long query only works when I fetch 1 row:
SELECT TOP 1 contcode, datime FROM #tbl
And if I don't use TOP 1, I get the error message of:
"Subquery returned more than 1 value...."
How can I fetch those two or more values in order, run the long query based each , not getting this error?
I think you just need to move the SET #counter = #counter + 1 up between the BEGIN...END block under your WHILE loop. That's probably why it only works for TOP 1, since 1 is <= COUNT(*).
DECLARE #r TABLE (id int IDENTITY (1,1),lnr char (9), pday datetime)
INSERT INTO #r (lnr, pday)
SELECT TOP 1 lnr, pday FROM memrepay
DECLARE #counter int SET #counter = 1
DECLARE #contcode char (9)
DECLARE #datime datetime
WHILE #counter <= (SELECT COUNT(*) FROM #r)
BEGIN
--long query
SET #counter = #counter + 1
END
END
SELECT * FROM #finaltable

Auto Increment userdefined id

Hi can anyone give me an idea how to create an auto generated id like ED01,ED02 etc., so that when i am entering data the id should be automatically incremented
Arguably this would be better done on the client side but you could
create a normal identity column
add a computed column doing the formatting.
Test script
DECLARE #ED TABLE (
ID INTEGER PRIMARY KEY IDENTITY(1, 1)
, UserID AS 'ED' + CAST(ID AS VARCHAR(32))
, I INTEGER
)
DECLARE #I INTEGER
SET #I = 0
WHILE #I < 100
BEGIN
SET #I = #I + 1
INSERT INTO #ED VALUES (#I)
END
SELECT * FROM #ED