How to pass parameters for OPENDATASOURCE - linked-server

I can connect to a linked server with this:
SELECT testNo, soruTuruId, soruNo, cevap , degerlendirenTcNo, degerlendirilenTcNo
FROM OPENDATASOURCE('SQLOLEDB', 'Data Source=192.168.150.42;User ID=readerUser;Password=1').akreditasyon.dbo.tblPerfCevap
But I have to pass the password as parameter. and I try like this:
SET #connectionString = 'Data Source=192.168.150.42;User ID=readerUser;Password='+#pw
SELECT testNo, soruTuruId, soruNo, cevap , degerlendirenTcNo, degerlendirilenTcNo
FROM OPENDATASOURCE('SQLOLEDB', #connectionString ).akreditasyon.dbo.tblPerfCevap
and
SELECT testNo, soruTuruId, soruNo, cevap , degerlendirenTcNo, degerlendirilenTcNo
FROM OPENDATASOURCE('SQLOLEDB', 'Data Source=192.168.150.42;User ID=readerUser;Password='+#pw ).akreditasyon.dbo.tblPerfCevap
but didnt work:S
does anyone have an idea?

use exec () function to run the query. Wrap your query into a valid string.

Here's my working implementation of Ojulari's answer. I wanted the same stored proc to run from our Prod, QA, etc.. environment, each one needs to access a different BizTalk Server's database.
declare #DataSource varchar(100)
set #DataSource =
case
when dbo.GetEnvironment() = 'PROD' then 'Data Source=ProdBizTalkServer;UID=test;PWD=test'
when dbo.GetEnvironment() = 'QA' then 'Data Source=QABizTaklServer;UID=test;PWD=test'
ELSE null
end
declare #myExec varchar(max)
set #myExec = 'select
nvcMessageType,
COUNT(*)
from OpenDataSource(''SQLNCLI10'',''' + #DataSource + ''').BizTalkMsgBoxDb.dbo.Spool
where nvcMessageType like ''%#FlightMessageReceivedEvent''
group BY nvcMessageType
order by nvcMessageType
'
print '#myExec=' + IsNull(#myExec,'null')
EXEC(#myExec)

Related

How to get the sql print message using pymssql

I'm running some queries, that print runtime stats from their execution.
It's done through
print('message')
used within the sql script.
I would want to see these messages while calling the procedures/scripts through pymssql.
conn = pymssql.connect(server, user, password, "tempdb")
cursor = conn.cursor()
cursor.execute("print('message')")
conn.commit()
Above script doesn't return anything, and I can't find any tips on how to get that print to show up in the console output.
Found a solution that let's me still use pymssql and get the print messages.
pymssql.Connection actually uses _mssql.MSSQLConnection internally.
This means that you can use this example by accessing that internal object.
connection = pymssql.connect(server='server_address', database='db_name')
connection._conn.set_msghandler(my_msg_handler) # Install our custom handler
where the my_msg_handler is the same type of object as in pmssql wiki.
Accessing internal objects is not ideal, but it's the only way I've found if you don't want to use a different library and need to get the SQL prints.
I don't believe there is a way, but you can refactor your SQL. For example:
DECLARE #my_var AS VARCHAR(200)
PRINT 'Setting a variable...'
SET #my_var = 'this'
PRINT 'I am some output'
SELECT * FROM my_table WHERE this = #my_var
Could be refactored to be something like this:
DECLARE #my_var AS VARCHAR(200)
DECLARE #messages AS VARCHAR(MAX)
SET #messages = #messages + 'Setting a variable...'
SET #my_var = 'this'
SET #messages = #messages + 'I am some output'
SELECT #messages, * FROM my_table WHERE this = #my_var
Good luck!
In order to print something into the console in pymssql, you don't need to put the print inside the execute function. you can simply use
print("message")
so your code will be
conn = pymssql.connect(server, user, password, "tempdb")
cursor = conn.cursor()
print("message")
conn.commit()

Creating a new table in sqlite database [duplicate]

I'm having some strange feeling abour sqlite3 parameters that I would like to expose to you.
This is my query and the fail message :
#query
'SELECT id FROM ? WHERE key = ? AND (userid = '0' OR userid = ?) ORDER BY userid DESC LIMIT 1;'
#error message, fails when calling sqlite3_prepare()
error: 'near "?": syntax error'
In my code it looks like:
// Query is a helper class, at creation it does an sqlite3_preprare()
Query q("SELECT id FROM ? WHERE key = ? AND (userid = 0 OR userid = ?) ORDER BY userid DESC LIMIT 1;");
// bind arguments
q.bindString(1, _db_name.c_str() ); // class member, the table name
q.bindString(2, key.c_str()); // function argument (std::string)
q.bindInt (3, currentID); // function argument (int)
q.execute();
I have the feeling that I can't use sqlite parameters for the table name, but I can't find the confirmation in the Sqlite3 C API.
Do you know what's wrong with my query?
Do I have to pre-process my SQL statement to include the table name before preparing the query?
Ooookay, should have looked more thoroughly on SO.
Answers:
- SQLite Parameters - Not allowing tablename as parameter
- Variable table name in sqlite
They are meant for Python, but I guess the same applies for C++.
tl;dr:
You can't pass the table name as a parameter.
If anyone have a link in the SQLite documentation where I have the confirmation of this, I'll gladly accept the answer.
I know this is super old already but since your query is just a string you can always append the table name like this in C++:
std::string queryString = "SELECT id FROM " + std::string(_db_name);
or in objective-C:
[#"SELECT id FROM " stringByAppendingString:_db_name];

Teradata : How to get the server name using query

How can I get the server name using query in Teradata?
That is, if I am writing a query on the 'dev' server, it should return the dev server name.
for example, in Sybase : we will be using select ##servername.
There's nothing like ##servername in TD.
You might create a SQL UDF on each server returning the name, e.g.
REPLACE FUNCTION syslib.#servername ()
RETURNS VARCHAR(30)
LANGUAGE SQL
CONTAINS SQL
DETERMINISTIC
RETURNS NULL ON NULL INPUT
SQL SECURITY DEFINER
COLLATION INVOKER
INLINE TYPE 1
RETURN 'dev'
If it's created in syslib it can be accessed without qualifying it like this:
SELECT #servername();
SELECT CASE
WHEN LogonSource LIKE '%UAT%' THEN 'UAT'
WHEN LogonSource LIKE '%PROD%' THEN 'Prod'
ELSE 'Unknown'
END DatabaseName
FROM DBC.SessionInfoV
WHERE UserName = 'myname';
This will give you information close to ##servername.
select ClientTdHostName, ServerIPAddrByServer, ServerPortByServer
from DBC.SessionInfo where SessionNo=Session;
Validated against 17.xx TD.

How to search my database by using an array of words?

I'm attempting to setup a search function from a string a user types. (ex: "John Doe" or "Doe, John")
I was thinking I would use Replace(SearchString, ",", "") to get rid of the commas the user might enter, and then use Split(SearchString, " ") to get all the words into an array. Once they're in the array I would execute a Stored Procedure on each of the terms and build a DataTable with the results.
Below is what I'm wanting to use for executing my stored procedure.
oCommand = DataAccess.GetSQLCommand("MyStoredProcedure", CommandType.StoredProcedure, SourceServer.ConnectionLocal)
oCommand.Parameters.AddWithValue("#MySearchString", SearchString)
oAdapter = New SqlDataAdapter(oCommand)
oAdapter.Fill(MyDataTable)
Now I'm thinking the "SearchString" I will assign while looping through my array of words... but this doesn't seem like the right way to do this. Maybe it is but I don't know how to append my next result to the previous DataTable either.
There are some great ideas for using arrays and Lists in SQL Server on this page - http://www.sommarskog.se/arrays-in-sql-2005.html
I personally find the XML method the most useful;
http://www.sommarskog.se/arrays-in-sql-2005.html#XML
An example of how I've used this in the past is;
DECLARE #indata nvarchar(max)
DECLARE #hDoc int
SET #indata = '
<ROOT>
<SearchTerm code="Test search term"></SearchTerm>
<SearchTerm code="Other search term"></SearchTerm>
<SearchTerm code="Next search term"></SearchTerm>
</ROOT>'
CREATE TABLE #searchTerm (
code varchar(40)
)
EXEC sp_xml_preparedocument #hDoc OUTPUT, #indata
INSERT Into #searchTerm
SELECT code
FROM OPENXML(#hDoc, '/ROOT/SearchTerm',1)
WITH (code varchar(50))
EXEC sp_xml_removedocument #hDoc
-- Use the data in #searchTerm as needed in your query
SELECT * FROM MyTable WHERE searchValue IN (SELECT code FROM #searchTerm)
DROP TABLE #searchTerm
Try passing in the comma separated values in as a single string of nvarchar. Then use the SELECT FROM WHERE IN structure within your stored procedure. Create the sql command wwithin your stored procedure by concatenation and then call EXEC #sql
Declare #sql =
'SELECT * FROM tbl
WHERE person IN(' + #Application + ')'
exec(#sql)
Beware, if your list of search criteria is large this may not be the best solution for you.
Note that the commas should be between the full names not the first name and last name.

Preferred Method to Catch Specific OleDB Error

Ok - I have a situation in which I must execute a dynamically built stored procedure against tables that may, or may not be in the database. The data retrieved is then shunted to a VB.Net backed ASP based report page. By design, if the tables are not present in the database, the relevant data is automatically hidden on the report page. Currently, I'm doing this by checking for the inevitable error, and hiding the div in the catch block. A bit kludgy, but it worked.
I can't include the VB code-behind, but the relevant stored procedure is included below.
However, a problem with this method was recently brought to my attention when, for no apparent reason, the div was being hidden even though the proper data was available. As it turned out, the user trying to select the table in the dynamic SQL call didn't have the proper select permissions, an easy enough fix once I could track it down.
So, two fold question. First and foremost - is there a better way to check for a missing table than through catching the error in the VB.Net codebehind? All things considered, I'd rather save the error checking for an actual error. Secondly, is there a preferred method to squirrel out a particular OLE DB error out of the general object caught by the try->catch block other than just checking the actual stack trace string?
SQL Query - The main gist of the code is that, due to the design of the database, I have to determine the name of the actual table being targeted manually. The database records jobs in a single table, but each job also gets its own table for processing data on the items processed in that job, and it's data from those tables I have to retrieve. Absolutely nothing I can do about this setup, unfortunately.
DECLARE #sql NVarChar(Max),
#params NVarChar(Max),
#where NVarChar(Max)
-- Retained for live testing of stored procedure.
-- DECLARE #Table NvarChar(255) SET #Table = N'tblMSGExportMessage_10000'
-- DECLARE #AcctID Integer SET #AcctID = 10000
-- DECLARE #Type Integer SET #Type = 0 -- 0 = Errors only, 1 = All Messages
-- DECLARE #Count Integer
-- Sets our parameters for our two dynamic SQL calls.
SELECT #params = N'#MsgExportAccount INT, #cnt INT OUTPUT'
-- Sets our where clause dependent upon whether we want all results or just errors.
IF #Type = 0
BEGIN
SELECT #where =
N' AND ( mem.[MSGExportStatus_OPT_CD] IN ( 11100, 11102 ) ' +
N' OR mem.[IngestionStatus_OPT_CD] IN ( 11800, 11802, 11803 ) ' +
N' OR mem.[ShortcutStatus_OPT_CD] IN ( 11500, 11502 ) ) '
END
ELSE
BEGIN
SELECT #where = N' '
END
-- Retrieves a count of messages.
SELECT #sql =
N'SELECT #cnt = Count( * ) FROM dbo.' + QuoteName( #Table ) + N' AS mem ' +
N'WHERE mem.[MSGExportAccount_ID] = #MsgExportAccount ' + #where
EXEC sp_executesql #sql, #params, #AcctID, #cnt = #Count OUTPUT
To avoid an error you could query the sysobjects table to find out if the table exists. Here's the SQL (replace YourTableNameHere). If it returns > 0 then the table exists. Create a stores procedure on the server that runs this query.
select count(*)
from sysobjects a with(nolock)
where a.xtype = 'U'
and a.name = 'YourTableNameHere'

Resources