Вставка случайных записей и хранимых процедур SQL2005 - PullRequest
2 голосов
/ 16 июля 2009

Мне нужно отправить данные из формы в базу данных SQL2005 с помощью хранимой процедуры. Сложность состоит в том, что мне также нужно получить 5 случайных записей из вторичной таблицы и вставить их как часть вставленной записи в таблицу 1.

Моя структура сродни этому:


Tbl_Organisations (таблица для получения 5 случайных записей)

Ключ | имя_организации |


Tbl_Campaigns (таблица для вставки)

Ключ | имя | дата | организация_1 | организация_2 | организация_3 | и т.д ........


Мне нужно получить 5 уникальных / случайных записей из 'tbl_Organisations', поймать их и вставить в одну запись вместе с данными, введенными в хранимую процедуру. Я понимаю, что массивы не вариант в SQL2005 (?).

Итак, как мне перехватить эти записи и затем вставить их как одну запись вместе с входами SP?

Любая помощь будет принята с благодарностью, так как я изо всех сил стараюсь разобраться со сложностями SQL

Спасибо.

Ответы [ 2 ]

0 голосов
/ 16 июля 2009

это должно работать, если у вас есть последовательный цифровой ключ (например, идентификатор), и вы никогда не удаляете какие-либо строки или не откатываете какие-либо транзакции. Вы не публикуете много подробностей, так что это всего лишь предположение, на котором вы можете основывать свой код. Если вы удаляете строки, вы можете использовать ROW_NUMBER (), чтобы аналогичный подход работал.

из здесь , попробуйте это:

DECLARE @Random1 INT;
DECLARE @Random2 INT;
DECLARE @Random3 INT;
DECLARE @Random4 INT;
DECLARE @Random5 INT;
DECLARE @Upper INT;
DECLARE @Lower INT

---- This will create a random number between 1 and count() of table
SET @Lower = 1 ---- The lowest random number
SELECT @Upper= COUNT(*) FROM Tbl_Organisations ---- The highest random number
SELECT @Random1 = ROUND(((@Upper - @Lower -1) * RAND() + @Lower), 0)
SELECT @Random2 = ROUND(((@Upper - @Lower -1) * RAND() + @Lower), 0)
SELECT @Random3 = ROUND(((@Upper - @Lower -1) * RAND() + @Lower), 0)
SELECT @Random4 = ROUND(((@Upper - @Lower -1) * RAND() + @Lower), 0)
SELECT @Random5 = ROUND(((@Upper - @Lower -1) * RAND() + @Lower), 0)

INSERT INTO Tbl_Campaigns (...., organisation_1,organisation_2,organisation_3...)
SELECT
    ...., t1.organisation_name, t2.organisation_name,t3.organisation_name...
    FROM Tbl_Organisations            t1
        INNER JOIN  Tbl_Organisations t2 ON t2.key=@Random2
        INNER JOIN  Tbl_Organisations t3 ON t3.key=@Random3
        INNER JOIN  Tbl_Organisations t4 ON t4.key=@Random4
        INNER JOIN  Tbl_Organisations t5 ON t5.key=@Random5
    WHERE t1.key=@Random1

РЕДАКТИРОВАТЬ в зависимости от необходимости использовать row_number ()

попробуйте этот код:

--set up tables
DECLARE @Tbl_Organisations table (O_KeyID int not null primary key identity(1,1), organisation_name varchar(20) not null)
DECLARE @Tbl_Campaigns table (C_KeyID int not null primary key identity(1,1), Cname varchar(10), createdate datetime, organisation_1 int, organisation_2 int, organisation_3 int, organisation_4 int, organisation_5 int)

--set up data
INSERT INTO @Tbl_Organisations VALUES ('one')
INSERT INTO @Tbl_Organisations VALUES ('two')
INSERT INTO @Tbl_Organisations VALUES ('three')
INSERT INTO @Tbl_Organisations VALUES ('pine')
INSERT INTO @Tbl_Organisations VALUES ('oak')
INSERT INTO @Tbl_Organisations VALUES ('maple')
INSERT INTO @Tbl_Organisations VALUES ('car')
INSERT INTO @Tbl_Organisations VALUES ('train')
INSERT INTO @Tbl_Organisations VALUES ('boat')
INSERT INTO @Tbl_Organisations VALUES ('dog')
INSERT INTO @Tbl_Organisations VALUES ('cat')
INSERT INTO @Tbl_Organisations VALUES ('horse')
INSERT INTO @Tbl_Organisations VALUES ('square')
INSERT INTO @Tbl_Organisations VALUES ('triangle')
INSERT INTO @Tbl_Organisations VALUES ('circle')

--temp areas to hold the 5 random numbers
DECLARE @Random1 INT;
DECLARE @Random2 INT;
DECLARE @Random3 INT;
DECLARE @Random4 INT;
DECLARE @Random5 INT;

--temp areas to hold the ranges to generate random numbers within
DECLARE @Upper INT;
DECLARE @Lower INT
DECLARE @range int

--get values to determine ranges of random numbers,
SET @Lower = 1 ---- The lowest random number
SELECT @Upper= COUNT(*) FROM @Tbl_Organisations ---- The highest random number
SET @Range=(@Upper - @Lower)/5


--will divide the @Tbl_Organisations table in to 5 ranges and select a random number from each range
--set the lower and upper limit on range 1
SELECT @Upper=@Lower+@Range
PRINT '@Lower='+CONVERT(varchar(50),@Lower)+', @Upper='+CONVERT(varchar(50),@Upper)
--get a random value from range 1
SELECT @Random1 = ROUND(((@Upper - @Lower -1) * RAND() + @Lower), 0)

--set the lower and upper limit on range 2
SELECT @Lower=@Upper+1,@Upper=@Lower+@Range
PRINT '@Lower='+CONVERT(varchar(50),@Lower)+', @Upper='+CONVERT(varchar(50),@Upper)
--get a random value from range 2
SELECT @Random2 = ROUND(((@Upper - @Lower -1) * RAND() + @Lower), 0)

--set the lower and upper limit on range 3
SELECT @Lower=@Upper+1,@Upper=@Lower+@Range
PRINT '@Lower='+CONVERT(varchar(50),@Lower)+', @Upper='+CONVERT(varchar(50),@Upper)
--get a random value from range 3
SELECT @Random3 = ROUND(((@Upper - @Lower -1) * RAND() + @Lower), 0)

--set the lower and upper limit on range 4
SELECT @Lower=@Upper+1,@Upper=@Lower+@Range
PRINT '@Lower='+CONVERT(varchar(50),@Lower)+', @Upper='+CONVERT(varchar(50),@Upper)
--get a random value from range 4
SELECT @Random4 = ROUND(((@Upper - @Lower -1) * RAND() + @Lower), 0)

--set the lower and upper limit on range 5
SELECT @Lower=@Upper+1,@Upper=COUNT(*) FROM @Tbl_Organisations
PRINT '@Lower='+CONVERT(varchar(50),@Lower)+', @Upper='+CONVERT(varchar(50),@Upper)
--get a random value from range 5
SELECT @Random5 = ROUND(((@Upper - @Lower -1) * RAND() + @Lower), 0)


--this uses a CTE names "RowNumbers" to enumerate @Tbl_Organisations with a column "RowNumber" that is a unique sequential continueous from 1 to count(*) of @Tbl_Organisations
;with RowNumbers AS
(
    SELECT O_KeyID, row_number() over(order by O_KeyID) AS RowNumber from @Tbl_Organisations
)
--one row will be inserted, using the 5 joined in @Tbl_Organisations
INSERT INTO @Tbl_Campaigns (Cname,createdate, organisation_1, organisation_2, organisation_3, organisation_4, organisation_5)
--this will select and combine the 5 rows into 1 row, using the rownumber joined to the variables with the random values
SELECT
    'YourName'
        ,getdate()
        ,t1.O_KeyID --could be t1.organisation_name
        ,t2.O_KeyID --could be t2.organisation_name
        ,t3.O_KeyID --could be t3.organisation_name
        ,t4.O_KeyID --could be t4.organisation_name
        ,t5.O_KeyID --could be t5.organisation_name
    from @Tbl_Organisations           t1
        inner join @Tbl_Organisations t2 on t2.O_KeyID=@Random2
        inner join @Tbl_Organisations t3 on t3.O_KeyID=@Random3
        inner join @Tbl_Organisations t4 on t4.O_KeyID=@Random4
        inner join @Tbl_Organisations t5 on t5.O_KeyID=@Random5
    WHERE t1.O_KeyID=@Random1

--this shows the one row that was inserted
SELECT 'all unique',* FROM @Tbl_Campaigns 

вот вывод

(1 row(s) affected)

(1 row(s) affected)

(1 row(s) affected)

(1 row(s) affected)

(1 row(s) affected)

(1 row(s) affected)

(1 row(s) affected)

(1 row(s) affected)

(1 row(s) affected)

(1 row(s) affected)

(1 row(s) affected)

(1 row(s) affected)

(1 row(s) affected)

(1 row(s) affected)

(1 row(s) affected)
@Lower=1, @Upper=3
@Lower=4, @Upper=6
@Lower=7, @Upper=9
@Lower=10, @Upper=12
@Lower=13, @Upper=15

(1 row(s) affected)
           C_KeyID     Cname      createdate              organisation_1 organisation_2 organisation_3 organisation_4 organisation_5
---------- ----------- ---------- ----------------------- -------------- -------------- -------------- -------------- --------------
all unique 1           YourName   2009-07-16 12:14:04.590 2              4              7              10             14

(1 row(s) affected)
0 голосов
/ 16 июля 2009

Случайные записи можно получить, добавив ORDER BY NEWID() в конце запроса во 2-ю таблицу. Конечно, используйте TOP 5 в начале, чтобы вернуть только 5 строк.

Затем используйте цикл курсора SQL по возвращенным строкам, чтобы заполнить 5 статических переменных (@var1, @var2 и т. Д.), Которые будут использоваться при окончательной вставке в 1-ю таблицу. Вам нужно будет использовать счетчик цикла и некоторые операторы CASE, чтобы выяснить, какую переменную нужно заполнить при каждом прохождении цикла. Наконец, убедитесь, что вы обрабатываете случай, когда возвращается менее 5 строк, если это возможно с вашим набором данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...