I try to filter data by a few numbers, cant use IN because it requires string value. How can I do this?
I tried sth like this but it doesn't work. How can I pas A FEW int values to filter?
You can create a parameter (filter) in your report that will accept numbers separated by , or some other character. That parameter will be string and it will look like this:
In SQL procedure separate those values using SPLIT_STRING function.
Here's a simple example.
CREATE TABLE #Numbers ( Num INT )
INSERT INTO #Numbers (Num) VALUES(1)
INSERT INTO #Numbers (Num) VALUES(2)
INSERT INTO #Numbers (Num) VALUES(3)
INSERT INTO #Numbers (Num) VALUES(4)
INSERT INTO #Numbers (Num) VALUES(5)
Task is to select some values from #Numbers table. Values to be selected are:
DECLARE #MyValues CHAR(100) = '1, 3, 5, 7'
In your example #MyValues is report parameter.
Those values will be separated by:
DECLARE #Separator CHAR = ','
Next step is to separate #MyValues and store them:
CREATE TABLE #SplitValues ( NumValues INT )
INSERT INTO #SplitValues
SELECT TRIM(Value) FROM STRING_SPLIT(#MyValues, #Separator)
Last step is to select #MyValues from #Numbers table:
SELECT * FROM #Numbers
WHERE
Num IN (SELECT * FROM #SplitValues)
Instead of using #SplitValues table there is an option of using SELECT TRIM(Value) FROM STRING_SPLIT(#MyValues, #Separator) directly in the last select, however, that way functions TRIM and SPLIT_STRING are called for every row in #Numbers table, which is "heavier" to execute.
Finally, instead of a string parameter, you can create a drop-down checkbox list and pass its values the same way, as a string that contains numbers separated by coma.
Related
I have a table with 2 columns, one column with Alphabetic character and other column with value. Example
A 1
B 2
C 3
D 4
E 5
Now I would like to get the sum of all digits corresponding to characters containing in a string.
Like BAD = (2+1+4) = 7
Please suggest how this can be done in mysql (sql/procedure)
You can use the following solution:
I used the following to setup the table with the characters and their numeric values:
-- create the table for char values.
CREATE TABLE charValues (
charItem VARCHAR(1),
charValue INT
);
-- insert the values to the table.
INSERT INTO charValues VALUES
('A', 1),
('B', 2),
('C', 3),
('D', 4),
('E', 5);
To get the count of each character on your value, you can use the following FUNCTION (in this case named getCharCount). This FUNCTION was created on the following solution and can be used in this case to get the count of each character:
-- function to count the count of a character.
CREATE FUNCTION getCharCount (colValue VARCHAR(255), searchValue CHAR(1))
RETURNS INT DETERMINISTIC
RETURN (CHAR_LENGTH(colValue) - CHAR_LENGTH(REPLACE(colValue, searchValue, '')));
Now you can add a second FUNCTION to get the SUM of the value:
DELIMITER //
CREATE FUNCTION getStrSum (colValue VARCHAR(255))
RETURNS INT NO SQL
BEGIN
DECLARE retVal INT;
SELECT SUM(getCharCount(colValue, charItem) * charValue) INTO retVal FROM charValues;
RETURN retVal;
END //
Now you can use the following SELECT statement to get the calculated result based on table charValues. The functions can be used on the whole database like this:
SELECT getStrSum('BAD') -- output: 7
SELECT getStrSum('DAD') -- output: 9
Have a table "json_test" and inserted the following record:
create table json_test ( v json);
insert into json_test values ('{"facilityId": ["20","30","40","50","51"]}')
SELECT trim(json_array_elements_text(v->'facilityId') ) from json_test
The above select lists the facility ID as individual rows.
I need the same rows in a Postgres function to insert the record into another table. I wrote the following code to return i. The output of the v_status when checked is (20,,,,,,,,,,,,). I need to get just 20, but I am unable to get that.
for i in SELECT json_array_elements_text(v->'facilityId') from json_test
loop
v_status:= i;
end loop;
You have not specified entire function definition in your question.
Assuming you have DDL:
CREATE TABLE json_test(
id SERIAL PRIMARY KEY,
v JSON
);
INSERT INTO json_test(v) VALUES
('{"facilityId": ["20","30","40","50","51"]}'::JSON);
You can check full PL/pgSQL guide as a reference, but your function may be defined as the following:
CREATE OR REPLACE FUNCTION get_facility_ids(rid INTEGER)
RETURNS SETOF INTEGER AS $$
DECLARE
t TEXT;
BEGIN
FOR t IN SELECT json_array_elements_text(v->'facilityId')
FROM json_test WHERE id = rid
LOOP
RETURN NEXT t;
END LOOP;
END;
$$ LANGUAGE plpgsql;
SELECT get_facility_ids(1) AS facultyId;
Just for your information, you can INSERT records from SELECT statements. Check the documentation.
I have a stored procedure that accepts a string such as A, B, C...etc. I want to split the string and insert each letter as one record into a table. The result should be:
col1 col2
1 A
2 B
3 C
I could use cursor, but cursor is kind of slow if I call this stored procedure from my web page. Is there any better solution?
Instead of passing a comma-separated string, pass a table-valued parameter. First, create a table type in your database:
CREATE TYPE dbo.Strings AS TABLE(String NVARCHAR(32));
Then your stored procedure:
CREATE PROCEDURE dbo.InsertStrings
#Strings dbo.Strings READONLY
AS
BEGIN
SET NOCOUNT ON;
INSERT dbo.Table(Col2) -- assuming col1 is an IDENTITY column?
SELECT String FROM #Strings;
END
GO
Then in your C# code or whatever, you just pass a DataTable as a Structured parameter. Example here and background here.
If you really don't want to do this, because it's too hard or whatever, then you can use a much less efficient string splitting function, e.g.
CREATE FUNCTION [dbo].[SplitString]
(
#List NVARCHAR(MAX),
#Delim VARCHAR(255)
)
RETURNS TABLE
AS
RETURN ( SELECT [Value] FROM
(
SELECT
[Value] = LTRIM(RTRIM(SUBSTRING(#List, [Number],
CHARINDEX(#Delim, #List + #Delim, [Number]) - [Number])))
FROM (SELECT Number = ROW_NUMBER() OVER (ORDER BY name)
FROM sys.all_objects) AS x
WHERE Number <= LEN(#List)
AND SUBSTRING(#Delim + #List, [Number], LEN(#Delim)) = #Delim
) AS y
);
Then your procedure is:
CREATE PROCEDURE dbo.InsertStrings
#Strings NVARCHAR(MAX)
AS
BEGIN
SET NOCOUNT ON;
INSERT dbo.Table(Col2) -- assuming col1 is an IDENTITY column?
SELECT [Value] FROM dbo.SplitString(#Strings, ',');
END
GO
Since this can not be done like :
select * from (call my_stored_procedure(params));
Is there any alternative for the above statement ?
A procedure could return multiple result sets, each with its own schema. It's not suitable for using in a SELECT statement.
User-defined function could be an option. Here's an example:
CREATE FUNCTION CubicVolume
-- Input dimensions in centimeters
(#CubeLength decimal(4,1), #CubeWidth decimal(4,1),#CubeHeight decimal(4,1) )
RETURNS decimal(12,3) -- Cubic Centimeters.
AS
BEGIN
RETURN ( #CubeLength * #CubeWidth * #CubeHeight )
END
more on this link : http://msdn.microsoft.com/en-us/library/aa175085%28SQL.80%29.aspx
Create a temporary table variable and insert sp values into it, like :
Declare #t table
(
--column numbers will be equals to the numbers return by SP
)
Insert Into #t
call my_stored_procedure(params)
Select * From #t
desperately need an sp to pass mutiple values for the single variable like #list is a variable and the values I'm putting for it are '1,3,4,5,66' and I need information from the table realated to these id's:
SELECT T.C.value('.', 'NVARCHAR(100)') AS [id]
INTO #tblPersons
FROM (SELECT CAST ('<Name>' + REPLACE(#empid, ',', '</Name><Name>') + '</Name>' AS XML) AS [Names]) AS A
cross APPLY Names.nodes('/Name') as T(C)
I'm using this in my sp but I'm getting difficulty for passing this for the mutiple values.
Have you thought about using table variables to pass data to a stored procedure. Example:
Setup
CREATE TYPE EmpIdValuesType AS TABLE
(
[EmpID] [int]NOT NULL
)
CREATE TABLE Employee
(
EmpID INT,
Name varchar(20)
)
INSERT INTO Employee
Values
(1, 'test1'),
(2, 'test2'),
(3, 'test3'),
(4, 'test4'),
(5, 'test5'),
(6, 'test6'),
(7, 'test7');
Create Procedure usp_GetEmployees
(
#TableVariable EmpIdValuesType READONLY
)
AS
SELECT *
FROM Employee
INNER JOIN #TableVAriable TV
ON Employee.EmpId = TV.EmpId
Now you can insert rows into a temporary table variable of type EmpIdValuesType and pass the variable to the stored procedure:
Calling the Stored Procedure
DECLARE #empIds AS EmpIdValuesType
INSERT INTO #empIds(EmpID) Values (1), (2), (5)
Exec usp_GetEmployees #empIds;
And here are the results:
SQLFiddle