I want search in my asp.net page. In this page user types in a name in a textbox and then selects one value from a combobox that has two values (ascending, descending), she/he also must select one choice from a radio button list (price, add_date, name).
Now these parameters post to database. What can be stored procedure in SQL Server 2008 that shows data of my Product table based on these parameters?
My table is Product and has these columns: ID, Name, picture, Price, Added_date
When user for example types Camera in text field and selects Ascending and price, the result must be a table that show all camera based on their price in ascending order.
I really don't know what can be stored procedure? I'm new to databases. Please help me.
Try this:
Stored procedure:
CREATE PROCEDURE dbo.GetProducts
#Name NVARCHAR(100),
#SortOrder CHAR(10)
AS
BEGIN
IF #SortOrder = 'ASCENDING'
SELECT ID,[Name],Price,AddedDate FROM Product
WHERE [Name] LIKE '%' + #Name + '%'
ORDER BY [Name] ASC
ELSE IF #SortOrder = 'DESCENDING'
SELECT ID,[Name],Price,AddedDate FROM Product
WHERE [Name] LIKE '%' + #Name + '%'
ORDER BY [Name] DESC
END
And you execute it like this:
EXEC GetProducts #Name='Cam',#SortOrder='DESCENDING'
Related
I have create a table person(id, name ,samenamecount).The samenamecount attribute can be null but for each row can store the row count for same names.I am achieving this by calling a stored procedure inside a after insert trigger.Below is my code.
create or replace procedure automatic(s in person.name%type)
AS
BEGIN
update person set samenamecount=(select count(*) from person where name=s) where name=s;
END;
create or replace trigger inserttrigger
after insert
on person
for each row
declare
begin
automatic(:new.name);
end;
On inserting a row it is giving error like
table ABCD.PERSON is mutating, trigger/function may not see it.
Can somebody help me to figure out this?
If you have the table:
CREATE TABLE person (
id NUMBER
GENERATED ALWAYS AS IDENTITY
CONSTRAINT person__id__pk PRIMARY KEY,
name VARCHAR2(20)
NOT NULL
);
Then rather than creating a trigger, instead, you could use a view:
CREATE VIEW person_view (
id,
name,
samenamecount
) AS
SELECT id,
name,
COUNT(*) OVER (PARTITION BY name)
FROM person;
You can use the trigger:
CREATE TRIGGER inserttrigger
AFTER INSERT ON person
BEGIN
MERGE INTO person dst
USING (
SELECT ROWID AS rid,
COUNT(*) OVER (PARTITION BY name) AS cnt
FROM person
) src
ON (src.rid = dst.ROWID)
WHEN MATCHED THEN
UPDATE SET samenamecount = src.cnt;
END;
/
fiddle
If you want to make it more efficient then you could use a compound trigger and collate the names that are being inserted and only update the matching rows.
I need to identify tables that were created today by an interface, which I was able to do by using following query:
Note: The interface changes table names on daily basis.
SELECT [name] AS [TableName]
FROM sys.tables
WHERE NAME LIKE '_XYZExport_%'
AND CAST(create_date AS DATE) = CAST(GETDATE() AS DATE)
ORDER BY NAME
What I need:
Once the table names are pulled, I need dump its data into a new table. How can this be done easily?
Example:
Following tables returned from my queries:
_XYZExport_B02
_XYZExport_B12
_XYZExport_B22
I want to take these returned tables and insert their data into an existing Archive table using Union All.
Any help would be great!
You are on the right track with your "cursor" tag. I would recommend creating an insert statement and executing it each cursor loop.
DECLARE #TableName sysname
DECLARE #SQLInsert VARCHAR(100)
DECLARE TableNamesCursor CURSOR FAST_FORWARD READ_ONLY FOR
SELECT [name] AS [TableName]
FROM sys.tables
WHERE NAME LIKE '_XYZExport_%'
AND CAST(create_date AS DATE) = CAST(GETDATE() AS DATE)
ORDER BY NAME
OPEN TableNamesCursor
FETCH NEXT FROM TableNamesCursor INTO #TableName
WHILE ##FETCH_STATUS = 0
BEGIN
SET #SQLInsert = 'INSERT INTO ArchiveTable SELECT * FROM ' + #TableName
EXEC sp_executesql #SQLInsert
FETCH NEXT FROM TableNamesCursor INTO #TableName
END
CLOSE TableNamesCursor
DEALLOCATE TableNamesCursor
Hope that gets you going.
Noel
I have 4 locations Chennai, Banglore, Hyderabad, Mumbai.
Depending on user selection from dropdown, I need to gennerate an id like this:
If they select Chennai - CHE001,CH002,CHE002,CHE003,CHE004.....etc
If they select Mumbai - MUM001,MUM002,MUM003,MUM004.......etc
If they select Hyderabad - HYD001,HYD002,HYD003,HYD004........etc
like that in database it has to save
Like that auto generated id as has to save in database but it must be in unique.... I don't how it will work with SQL functions are stored procedure, asp.net .. please kindly help for this issue.
Declare #Selected varchar(100)='Chennai'
Select Stuff((Select Distinct ',' +ID
From (Select Top 999 ID=Upper(Left(#Selected,3))+Format(Row_Number() Over (Order By (Select null)),'000') From master..spt_values ) A
For XML Path ('')),1,1,'')
Returns
CHE001,CHE002,CHE003,CHE004,CHE005,CHE006,CHE007,CHE008,CHE009,CHE010,{...},CHE997,CHE998,CHE999
Or if you need rows
Declare #Selected varchar(100)='Chennai'
Select Top 999 ID=Upper(Left(#Selected,3))+Format(Row_Number() Over (Order By (Select null)),'000') From master..spt_values
Returns
ID
CHE001
CHE002
CHE003
CHE004
CHE005
{...}
CHE997
CHE998
CHE999
You can create stored procedure similar to below:
BEGIN
DECLARE #CITY VARCHAR(MAX) = 'MUMBAI'
DECLARE #CITYCODE VARCHAR(3) = SUBSTRING(#CITY,1,3)
INSERT INTO TBL (ID)
SELECT #CITYCODE + RIGHT('000' + CAST((CAST(REPLACE(ISNULL(MAX(ID),#CITYCODE + '000'),#CITYCODE,'') AS INT) + 1) AS VARCHAR),3)
FROM TBL
WHERE ID LIKE #CITYCODE + '%'
END
I'm working on a SQLite Database. The database is already filled, but I want to refactor it. Here is a sample of what I need to do:
I currently have one table:
CREATE TABLE Cars (ID INTEGER PRIMARY KEY,
Name VARCHAR(32),
TopSpeed FLOAT,
EngineCap FLOAT);
I want to split this into two tables:
CREATE TABLE Vehicles (ID INTEGER PRIMARY KEY,
Name VARCHAR(32),
TopSpeed FLOAT);
CREATE TABLE Cars (ID INTEGER PRIMARY KEY,
VehicleID INTEGER CONSTRAINT FK_Cars REFERENCES [Vehicles](ID),
EngineCap FLOAT);
I have figured out to create a temporary table with the Cars table contents, and I can fill up the Vehicles table with the contents of the Cars table:
CREATE TEMPORARY TABLE Cars_temp AS SELECT * FROM Cars;
INSERT INTO Vehicles (Name, TopSpeed)
SELECT Name, TopSpeed FROM Cars_temp;
But I am still looking for a way to go over that same selection, while putting the EngineCap field into the new Cars table and somehow extracting the corresponding ID value from the Vehicles table to put into the VehicleID foreign key field on the Cars table.
I'm open for workaround or alternative approaches.
Thanks.
Since #mateusza did not provide an example, I've made one:
Suppose you have this table:
CREATE TABLE [Customer] (
[name] TEXT,
[street] TEXT,
[city] TEXT);
Now you want to move street and city into a separate table Address, so you'll end up with two tables:
CREATE TABLE [Customer2] (
[name] TEXT,
[addr] INTEGER);
CREATE TABLE [Address] (
[rowid] INTEGER NOT NULL,
[street] TEXT,
[city] TEXT,
PRIMARY KEY ([rowid])
);
(For this example, I'm doing the conversion in the same database. You'd probably use two DBs, converting one into the other, with an SQL ATTACH command.)
Now we create a view (which imitates our original table using the new tables) and the trigger:
CREATE VIEW Customer1 (name, street, city) AS
SELECT C.name, A.street, A.city FROM Customer2 AS C
JOIN Address as A ON (C.addr == A.rowid);
CREATE TEMP TRIGGER TempTrig INSTEAD OF INSERT ON Customer1 FOR EACH ROW BEGIN
INSERT INTO Address (street, city) SELECT NEW.street, NEW.city;
INSERT INTO Customer2 (addr, name) SELECT last_insert_rowid(), NEW.name;
END;
Now you can copy the table rows:
INSERT INTO Customer1 (name, street, city) SELECT name, street, city FROM Customer;
The above is a simplified case where you'd only move some data into a single new table.
A more complex (and more general) case is where you want to...
Separate your original table's columns into several foreign tables, and
Have unique entries in the foreign tables (that's usually the reason why you'd refactor your table).
This adds some additional challenges:
You'll end up inserting into multiple tables before you can insert their rowids into the table with the referencing rowids. This requires storing the results of each INSERT's last_insert_rowid() into a temporary table.
If the value already exists in the foreign table, its rowid must be stored instead of the one from the (non-executed) insertion operation.
Here's a complete solution for this. It manages a database of music records, constisting of a song's name, album title and artist name.
-- Original table
CREATE TABLE [Song] (
[title] TEXT,
[album] TEXT,
[artist] TEXT
);
-- Refactored tables
CREATE TABLE [Song2] (
[title] TEXT,
[album_rowid] INTEGER,
[artist_rowid] INTEGER
);
CREATE TABLE [Album] (
[rowid] INTEGER PRIMARY KEY AUTOINCREMENT,
[title] TEXT UNIQUE
);
CREATE TABLE [Artist] (
[rowid] INTEGER PRIMARY KEY AUTOINCREMENT,
[name] TEXT UNIQUE
);
-- Fill with sample data
INSERT INTO Song VALUES ("Hunting Girl", "Songs From The Wood", "Jethro Tull");
INSERT INTO Song VALUES ("Acres Wild", "Heavy Horses", "Jethro Tull");
INSERT INTO Song VALUES ("Broadford Bazar", "Heavy Horses", "Jethro Tull");
INSERT INTO Song VALUES ("Statue of Liberty", "White Music", "XTC");
INSERT INTO Song VALUES ("Standing In For Joe", "Wasp Star", "XTC");
INSERT INTO Song VALUES ("Velvet Green", "Songs From The Wood", "Jethro Tull");
-- Conversion starts here
CREATE TEMP TABLE [TempRowIDs] (
[album_id] INTEGER,
[artist_id] INTEGER
);
CREATE VIEW Song1 (title, album, artist) AS
SELECT Song2.title, Album.title, Artist.name
FROM Song2
JOIN Album ON (Song2.album_rowid == Album.rowid)
JOIN Artist ON (Song2.artist_rowid == Artist.rowid);
CREATE TEMP TRIGGER TempTrig INSTEAD OF INSERT ON Song1 FOR EACH ROW BEGIN
INSERT OR IGNORE INTO Album (title) SELECT NEW.album;
UPDATE TempRowIDs SET album_id = (SELECT COALESCE (
(SELECT rowid FROM Album WHERE changes()==0 AND title==NEW.album), last_insert_rowid()
) ) WHERE rowid==1;
INSERT OR IGNORE INTO Artist (name) SELECT NEW.artist;
UPDATE TempRowIDs SET artist_id = (SELECT COALESCE (
(SELECT rowid FROM Artist WHERE changes()==0 AND name==NEW.artist), last_insert_rowid()
) ) WHERE rowid==1;
INSERT INTO Song2 (title, album_rowid, artist_rowid) SELECT
NEW.title, (SELECT album_id FROM TempRowIDs), (SELECT artist_id FROM TempRowIDs);
END;
INSERT INTO TempRowIDs DEFAULT VALUES;
INSERT INTO Song1 (title, album, artist) SELECT title, album, artist FROM Song;
DROP TRIGGER TempTrig;
DROP TABLE TempRowIDs;
-- Conversion ends here
-- Print results
SELECT * FROM Song;
SELECT * FROM Song1;
-- Check if original and copy are identical (https://stackoverflow.com/a/13865679/43615)
SELECT CASE WHEN (SELECT COUNT(*) FROM (SELECT * FROM Song UNION SELECT * FROM Song1)) == (SELECT COUNT() FROM Song) THEN 'Success' ELSE 'Failure' END;
Note that this example has one potential issue: If the constraints on the foreign table are more complex, the SELECT rowid FROM search for the existing entry needs to be updated accordingly. Ideally, SQLite should provide a way to determine the conflicting rowid somehow, but it doesn't, unfortunately (see this related question).
Simple solution without triggers:
create VEHICLES_TEMP table including the CAR_ID
create your new CARS table without the VEHICLES columns you don't want
update CARS with VEHICLE_ID taken from VEHICLES_TEMP (identified by the CAR_ID)
create final VEHICLES table without the CAR_ID
Create a table New_Cars and a INSTEAD OF INSERT trigger, which will insert data to both tables Vehicles and Cars. When inserting to Cars, you can use last_insert_rowid() function to refer to inserted row in Vehicles table.
This can be temporary solution, or you can leave it in your database for further modifications.
I have an insert statement that I can't get to work the way I want it to. It's on a vb.net page. This is on a VB.net page and I'm using SQL Server 2005 for my database.
Dim strSQL As String = "IF NOT EXISTS
(SELECT Title From Picklist)
BEGIN INSERT INTO Picklist (Title, Data)
VALUES (#Title, #Data);
INSERT INTO Marketing
(ProductID, MarketingTypeID, MarketingTitle, MarketingData)
VALUES (#ProductID, 9, 'Video', scope_identity()) END"
I don't get an error and nothing gets inserted into the database. If I try putting the END at the end of the first INSERT statement then I get an error saying that MarketingData is NULL and cannot be inserted.
But if I take out the IF NOT EXISTS from the statement, everything gets inserted perfectly. What am I doing wrong here?
UPDATE: Is it correct to write the statement like this?
INSERT INTO Marketing
SELECT (#ProductID, #MarketingTypeID, #MarketingTitle, #MarketingData)
WHERE NOT EXISTS
(SELECT * FROM Marketing)
Your IF NOT EXISTS(SELECT * FROM Picklist) will skip the insert if any rows at all exist in Picklist.
From your description of what happens when you change the position of the END it seems there are rows in the table.
I assume in fact you are trying to do an UPSERT. What version of SQL Server are you on? If 2008 look into MERGE
;WITH Source(Title, Data) AS
(
SELECT #Title, #Data
)
MERGE Picklist AS T
USING Source S
ON (T.Title = S.Title)
WHEN NOT MATCHED BY TARGET THEN
INSERT (Title, Data)
VALUES (#Title, #Data)
;
IF (##ROWCOUNT <> 0)
INSERT INTO Marketing
(ProductID, MarketingTypeID, MarketingTitle, MarketingData)
VALUES (#ProductID, 9, 'Video', scope_identity())