How do you set a variable in dremio?
In sql, normally you can do something like:
SET #ID = (SELECT id FROM table LIMIT 1)
or
SELECT #ID = (SELECT id FROM table LIMIT 1)
This does not seem to work for Dremio query. Anybody know how variables work in dremio?
This is not possible. We can't set variables in Dremio.
Dremio uses ANSI SQL where there is no such construct.
Related
I use basic sql querying for my day to day work, but I regularly find myself needing to run queries in different tables using the same where clauses.
What I would ideally like to do is locally set a value to a name, for example:
traderef = ABCD1234. It's kind of like Defining a name in excel.
and then use 'traderef' in my queries,
select * from table1 where tranid = traderef
select * from table2 where tranid = traderef and otherattr = 'xyz1'
I only have query access to the dbs that i use, i have tried to google results, and found some info re SET
TIA
Declare a bind variable using the SQL/Plus and SQL Developer command VARIABLE name data_type and assign it a value using EXECUTE (or a PL/SQL anonymous block) and then use it in your queries:
VARIABLE traderef VARCHAR2(20)
EXEC :traderef := 'ABCD1234';
SELECT * FROM table1 WHERE tranid = :traderef;
SELECT * FROM table2 HWERE tranid = :traderef AND otherattr = 'xyz1';
I was wondering if it is possible to set a declared variable to a return value from a select result? Something like:
#WatchedSeconds
SET #WatchedSeconds = 200
DECLARE #SelectedVideo int
SET #SelectedVideo = (SELECT TOP 1 * FROM Video v WHERE v.VideoID = 12)
IF #SelectedVideo IS NOT NULL
BEGIN
IF #SelectedVideo.VideoLength = #WatchedSeconds
BEGIN
--DO SOMETHING
END
IF #SelectedVideo.SomeOtherColumn = #SomethingElse
BEGIN
END
END
It's for using some information from the SELECT result multiple places in a Stored Procedure.
I know that I can set a variable to e.g, a integer, and set it to the selected result, if it returns a integer, e.g:
DECLARE #VideoSeconds int
SET #VideoSeconds = (SELECT v.Length FROM Video v WHERE v.VideoID = #VideoID)
This way I have to make multiple variables, and multiple SELECT calls if I need to use more values from the Video result. And that's what I want to avoid.
You can do this simply by running:
SELECT #videoSeconds = v.Length FROM Video v WHERE v.VideoID = #VideoID
so as to not add the SET part.
Also, you must make sure that only 1 row is being returned by the query, otherwise it will generate an error.
You can try something like
(declare variables first...)
SELECT TOP 1 #var1=col1, #var2=col2, #var3=col3, [...] FROM YourTable WHERE YourFilter
EDIT: All together this seems not to be the best approach... With SQL you should not think in values and single rows but rather in result sets (set based programming). Your thinking leads to many tiny selects, while loops, cursors and all this stuff one should avoid.
You can store the results in a temporary table or table variable:
SELECT TOP 1 *
INTO #SelectedVideo
FROM Video v
WHERE v.VideoID = 12;
Then you can assign values from the table later in your code. Something like:
IF ( (SELECT VideoLength FROM #SelectedVideo) = #WatchedSeconds)
However, for your particular example, if you have an index on video(VideoId), then there is little to be gained performance-wise from using a temporary table.
If what you're trying to get is similar to returning a dataset in a procedural language (so you can type something like Result.Field1 = 'Test') then I don't think this is possible. You'll just need to declare multiple variables and make the SELECT call as
SELECT TOP 1 #var1=col1, #var2=col2, #var3=col3, [...] FROM YourTable WHERE YourFilter
as #Shnugo suggests
The 'dataset' equivalent structure in SQL is cursors, but they require variables to be set up as well, so there's no benefit there.
how to update with a new variable
let's say I wanted to do the following
update T
set T.property1 = (declare #temp varch(20)
#temp = 'testing')
from #temp_table_name T
is this possible. I need to update a table but the new element is the end result of a series of complicated statements and it would be a lot easier to define some variables along the way to handle intermediate outputs. What is the correct syntax for what I'm trying to do above because it's not working
Is something like this what you're looking for?
DECLARE #temp varchar(20)
SET #temp = 'testing, or the result of a query maybe?'
UPDATE T SET T.property1 = #temp
FROM #temp_table_name T
WHERE 1 = 1
Move all of those statements into a scalar valued user-defined function and then in your update statement do this:
update T
set T.property1 = dbo.myUdf(...)
from #temp_table_name T
where ... are any parameters it may need from the row to do its job.
I need to use a temporary variable declared in stored procedure. I need to use this variable to assign a value and do some function in a Matched statement. How can I use? is there any other way to have value??
Thanks in advance
This is how you can define a local variable in SQL Server:
DECLARE #MyVariable INT
SET #MyVariable = 12
SELECT HouseNumber + #MyVariable as NewHouseNumber FROM MyTable WHERE Id = 1
If you declare the variable preceding the MERGE statement then you can indeed use that variable within the MERGE statement. This apples to table variables as well as scalar variables.
I think he ment something like this
MERGE TargetTable as tar
USING SourceTable as src
ON tar.SomeID = src.OtherID
DECLARE #BossId INT
SET #BossId = (SELECT ID FROM EmployeeTable WHERE [BossID] = src.BossID)
--Here we take dynamicly an ID from another table
WHEN NOT MATCHED THEN
INSERT (list OF fields, [BossID])
VALUES (list OF values, #BossId)
WHEN MATCHED THEN
UPDATE
SET (list OF SET statements);
This way in every INSERT statement will have different BossID. Is this even possible? If not - How to insert records this way? Imagine that the SourceTable (which in my case is an input parameter in a SP) came with ID which needs to be mapped with another talbe. Any suggestions?
My post is more like an addition to the original question.
We all know that prepared statements are one of the best way of fending of SQL injection attacks. What is the best way of creating a prepared statement with an "IN" clause. Is there an easy way to do this with an unspecified number of values? Take the following query for example.
SELECT ID,Column1,Column2 FROM MyTable WHERE ID IN (1,2,3)
Currently I'm using a loop over my possible values to build up a string such as.
SELECT ID,Column1,Column2 FROM MyTable WHERE ID IN (#IDVAL_1,#IDVAL_2,#IDVAL_3)
Is it possible to use just pass an array as the value of the query paramter and use a query as follows?
SELECT ID,Column1,Column2 FROM MyTable WHERE ID IN (#IDArray)
In case it's important I'm working with SQL Server 2000, in VB.Net
Here you go - first create the following function...
Create Function [dbo].[SeparateValues]
(
#data VARCHAR(MAX),
#delimiter VARCHAR(10)
)
RETURNS #tbldata TABLE(col VARCHAR(10))
As
Begin
DECLARE #pos INT
DECLARE #prevpos INT
SET #pos = 1
SET #prevpos = 0
WHILE #pos > 0
BEGIN
SET #pos = CHARINDEX(#delimiter, #data, #prevpos+1)
if #pos > 0
INSERT INTO #tbldata(col) VALUES(LTRIM(RTRIM(SUBSTRING(#data, #prevpos+1, #pos-#prevpos-1))))
else
INSERT INTO #tbldata(col) VALUES(LTRIM(RTRIM(SUBSTRING(#data, #prevpos+1, len(#data)-#prevpos))))
SET #prevpos = #pos
End
RETURN
END
then use the following...
Declare #CommaSeparated varchar(50)
Set #CommaSeparated = '112,112,122'
SELECT ID,Column1,Column2 FROM MyTable WHERE ID IN (select col FROM [SeparateValues](#CommaSeparated, ','))
I think sql server 2008 will allow table functions.
UPDATE
You'll squeeze some extra performance using the following syntax...
SELECT ID,Column1,Column2 FROM MyTable
Cross Apply [SeparateValues](#CommaSeparated, ',') s
Where MyTable.id = s.col
Because the previous syntax causes SQL Server to run an extra "Sort" command using the "IN" clause. Plus - in my opinion it looks nicer :D!
If you would like to pass an array, you will need a function in sql that can turn that array into a sub-select.
These functions are very common, and most home grown systems take advantage of them.
Most commercial, or rather professional ORM's do ins by doing a bunch of variables, so if you have that working, I think that is the standard method.
You could create a temporary table TempTable with a single column VALUE and insert all IDs. Then you could do it with a subselect:
SELECT ID,Column1,Column2 FROM MyTable WHERE ID IN (SELECT VALUE FROM TempTable)
Go with the solution posted by digiguru. It's a great reusable solution and we use the same technique as well. New team members love it, as it saves time and keeps our stored procedures consistent. The solution also works well with SQL Reports, as the parameters passed to stored procedures to create the recordsets pass in varchar(8000). You just hook it up and go.
In SQL Server 2008, they finally got around to addressing this classic problem by adding a new "table" datatype. Apparently, that lets you pass in an array of values, which can be used in a sub-select to accomplish the same as an IN statement.
If you're using SQL Server 2008, then you might look into that.
Here's one technique I use
ALTER Procedure GetProductsBySearchString
#SearchString varchar(1000),
as
set nocount on
declare #sqlstring varchar(6000)
select #sqlstring = 'set nocount on
select a.productid, count(a.productid) as SumOf, sum(a.relevence) as CountOf
from productkeywords a
where rtrim(ltrim(a.term)) in (''' + Replace(#SearchString,' ', ''',''') + ''')
group by a.productid order by SumOf desc, CountOf desc'
exec(#sqlstring)