google apps script jbdc sql server database connection string error - sql-server

I'm trying to connect to my local sql server database at my home network using the code that I found from this site Querying SQL Server with Google Apps Script via JDBC about 3 years ago which was marked being correct. However, I get the error message "We're sorry, a server error occurred. Please wait a bit and try again.". This error is from line 2 where the connection string is defined. I retried several times, but I always get the same error. When I searched this error, it seems like it could be too many things and I was not able to find any answers for my issue. Thanks.
This was the code that was marked being correct:
function readAzure() {
var conn = Jdbc.getConnection("jdbc:sqlserver://XYZ.database.windows.net:1433;databaseName=MYDATABSENAME","USERNAME","PASSWORD");
var stmt = conn.createStatement();
var rs = stmt.executeQuery("select * from helloworld");
var doc = SpreadsheetApp.create('azure');
var cell = doc.getRange('a1');
var row = 0;
while(rs.next()) {
cell.offset(row, 0).setValue(rs.getString(1));
cell.offset(row, 1).setValue(rs.getString(2));
row++;
}
rs.close();
stmt.close();
conn.close();
}
I also found another connection string code and when I try this format I get the same error.
var conn = Jdbc.getConnection("jdbc:sqlserver://IP-address:1433;" + "databaseName=DBName;user=username;password=password;");

Based on this documentation, you need to ensure that your database accepts connections from any of Apps Script's IP addresses. These are the address ranges you'll need to whitelist.
64.18.0.0 - 64.18.15.255
64.233.160.0 - 64.233.191.255
66.102.0.0 - 66.102.15.255
66.249.80.0 - 66.249.95.255
72.14.192.0 - 72.14.255.255
74.125.0.0 - 74.125.255.255
173.194.0.0 - 173.194.255.255
207.126.144.0 - 207.126.159.255
209.85.128.0 - 209.85.255.255
216.239.32.0 - 216.239.63.255
Also, from the documentation link above, there is a sample code that you can follow to set up external database via JDBC.
Here is a code that demonstrates how to write a single record to the database as well as a batch of 500 records.
// Replace the variables in this block with real values.
var address = 'database_IP_address';
var user = 'user_name';
var userPwd = 'user_password';
var db = 'database_name';
var dbUrl = 'jdbc:mysql://' + address + '/' + db;
// Write one row of data to a table.
function writeOneRecord() {
var conn = Jdbc.getConnection(dbUrl, user, userPwd);
var stmt = conn.prepareStatement('INSERT INTO entries '
+ '(guestName, content) values (?, ?)');
stmt.setString(1, 'First Guest');
stmt.setString(2, 'Hello, world');
stmt.execute();
}
// Write 500 rows of data to a table in a single batch.
function writeManyRecords() {
var conn = Jdbc.getConnection(dbUrl, user, userPwd);
conn.setAutoCommit(false);
var start = new Date();
var stmt = conn.prepareStatement('INSERT INTO entries '
+ '(guestName, content) values (?, ?)');
for (var i = 0; i < 500; i++) {
stmt.setString(1, 'Name ' + i);
stmt.setString(2, 'Hello, world ' + i);
stmt.addBatch();
}
var batch = stmt.executeBatch();
conn.commit();
conn.close();
var end = new Date();
Logger.log('Time elapsed: %sms for %s rows.', end - start, batch.length);
}
For more information, just read through to this documentation and check this thread and related SO question.

Related

attach database not work in Microsoft.Data.Sqlite (works in System.Data.Sqlite)

The following code works in System.Data.Sqlite. Recently I switched to Microsoft.Data.Sqlite, it gives error "Microsoft.Data.Sqlite.SqliteException: 'SQLite Error 14: 'unable to open database"
using (var command = _conn.CreateCommand())
{
var qAttach = #"ATTACH DATABASE 'file:C:\mydata\address.db?immutable=1' AS address";
command.CommandText = qAttach;
command.ExecuteNonQuery();
}

Running cmd from winform

I have a question about running cmd from winform.
I have managed to connect and get information from the remote machine(infotrend disk server).
However I could not make a operation on the remote machine such "create disk part
below I have written these code....
InfotrendProcess.StartInfo.UseShellExecute = false;
InfotrendProcess.StartInfo.RedirectStandardInput = true;
InfotrendProcess.StartInfo.RedirectStandardOutput = true;
InfotrendProcess.StartInfo.RedirectStandardError = true;
InfotrendProcess.StartInfo.WorkingDirectory = workingPath;
InfotrendProcess.StartInfo.FileName = "C:\\Windows\\System32\\cmd.exe";
InfotrendProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
InfotrendProcess.StartInfo.CreateNoWindow = true;
const string quote = "\"";
cmd_message = "java -jar " + quote + "runCLI" + quote; (MANAGED TO START CLI RUN COMMAND STEP 1)
InfotrendProcess.StartInfo.Arguments = "/K " + cmd_message;
InfotrendProcess.OutputDataReceived += InfotrendProcess_OutputDataReceived1;
InfotrendProcess.ErrorDataReceived += InfotrendProcess_ErrorDataReceived;
InfotrendProcess.Start();
using (StreamWriter sw = InfotrendProcess.StandardInput) (MANAGED TO CONNECT AND SEND DELETE
PART COMMAND STEP 2)
{
sw.WriteLine("connect " + IPNumber);
Thread.Sleep(1000);
sw.WriteLine("del part 01D9F2C6614DF837"); (COULD NOT SEND RESPOND y/s, MAKES NEW LINE)
sw.WriteLine("y")
}
I could not send the "y/n" respond because I have to send it in the same line after a period. Instead it makes a new line. Should I use a different way? Could anyone help me, how I can run the final command.

How to connect to SQL Server with R?

I want to create a model in R using a connection to data stored in SQL Server datawarehouse.
I tried to use RevoScaleR library which returned
package RevoScaleR is not available (for R version 3.4.1)
so, I edited the connection string (given on the code below) for ODBC library:
install.packages("RevoScaleR")
#require("RevoScaleR")
if (!require("RODBC"))
install.packages("RODBC")
conn <- odbcDriverConnect(connection="Driver={SQL Server Native Client 11.0}; Server=CZPHADDWH01/DEV; Database=DWH_Staging; trusted_connection=true")
sqlWait <- TRUE;
sqlConsoleOutput <- FALSE;
cc <- RxInSqlServer(connectionString = conn, wait = sqlWait)
rxSetComputeContext(cc)
train_query <- "SELECT TOP(10000) * FROM dim.Contract"
formula <- as.formula("Cosi ~ ContractID + ApprovedLoanAmount + ApprovedLoadDuration")
forest_model <- rxDForest(formula = formula,
data = train_query,
nTree = 20,
maxDepth = 32,
mTry = 3,
seed = 5,
verbose = 1,
reportProgress = 1)
rxDForest_model <- as.raw(serialize(forest_model, connection = conn))
lenght(rxDForest_model)
However:
package 'RODBC' successfully unpacked and MD5 sums checked
The downloaded binary packages are in
C:\Users\sjirak\AppData\Local\Temp\Rtmpqa9iKN\downloaded_packages
Error in odbcDriverConnect(connection = "Driver={SQL Server Native
Client 11.0}; Server=CZPHADDWH01/DEV; Database=DWH_Staging;
trusted_connection=true") : could not find function
"odbcDriverConnect" In library(package, lib.loc = lib.loc,
character.only = TRUE, logical.return = TRUE, : there is no
package called 'RODBC'
Any help would be appreciated.
Looking at the documentation of the ODBC, I see the following functions
odbc-package
dbConnect,OdbcDriver-method
dbUnQuoteIdentifier
odbc
odbc-tables
OdbcConnection
odbcConnectionActions
odbcConnectionIcon
odbcDataType
OdbcDriver
odbcListColumns
odbcListDataSources
odbcListDrivers
odbcListObjects
odbcListObjectTypes
odbcPreviewObject
OdbcResult
odbcSetTransactionIsolationLevel
test_roundtrip
hence I dont see your function in this list. This could be the reason why...
Hence, check the documentation for the proper function.

Exception: conversion from UNKNOWN to UNKNOWN is unsupported

I'm converting some jdbc code from MySql to SQL Server. When trying to
query = "Update ReportSetup "
+ "set N_ID=?, "
+ "R_Default=?, "
+ "R_Name=?, "
+ "R_Module=? "
+ " where R_ID = ?";
}
PreparedStatement stmt =
(PreparedStatement) con.prepareStatement(query, Statement.RETURN_GENERATED_KEYS);
stmt.setInt(1, ri.getNodeID());
stmt.setInt(2, (ri.isDefault()) ? 1 : 0);
stmt.setString(3, ri.getName());
Object o = ri.getReportModule();
stmt.setObject(4, o);
The last statement stmt.setObject(4,o) throws the exception.
ri.getReportModule returns an instance of a class which implements Externalizable.
The method writeExternal() of that class is implemented as
public final void writeExternal(final ObjectOutput objectOutput) throws IOException {
for (int i=0; i<pdV.size(); i++) {
PropertyDescriptor pd = pdV.elementAt(i);
try {
Method m = pd.getReadMethod();
Object val = pd.getReadMethod().invoke(this);
System.out.print("writing property " + i + ": " + pd.getName() + " = " + val);
objectOutput.writeObject(val);
} catch (Exception e) {
e.printStackTrace();
}
}
}
The database column in question is defined as
varbinary(max), not null
The code works well using MySql but I can't figure out what to do to make it run with Sql Server.
Any suggestions would be very much appreciated
The problem was that sql server is not happy to save a serialization (as done when implementing externalizable). .setObject() fails. The solution is to use setBinaryStream().
// Sql Server can't do an stmt.setObject(4,o) "Conversion from UNKNOWN to UNKNOWN not supported"
// Serialize the object to an output stream and then read it in again into the stmt.
Object o = ri.getReportModule();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream objectOutput = new ObjectOutputStream(bos);
objectOutput.writeObject(o);
objectOutput.flush();
InputStream objectInput = new ByteArrayInputStream(bos.toByteArray());
stmt.setBinaryStream(4, objectInput);
Cheers
Christian

Data encryption issues with Oracle Advanced Security

I have used Oracle Advanced Security to encrypt data during data transfer. I have successfully configured ssl with below parameters and I have restarted the instance. I am retrieving data from a Java class given below. But I could read the data without decrypting, the data is not getting encrypted.
Environment:
Oragle 11g database
SQLNET.AUTHENTICATION_SERVICES= (BEQ, TCPS, NTS)
SSL_VERSION = 0
NAMES.DIRECTORY_PATH= (TNSNAMES, EZCONNECT)
SSL_CLIENT_AUTHENTICATION = FALSE
WALLET_LOCATION =
(SOURCE =
(METHOD = FILE)
(METHOD_DATA =
(DIRECTORY = C:\Users\kcr\Oracle\WALLETS)
)
)
SSL_CIPHER_SUITES= (SSL_RSA_EXPORT_WITH_RC4_40_MD5)
Java class:
try{
Properties properties = Utils.readProperties("weka/experiment/DatabaseUtils.props");
// Security.addProvider(new oracle.security.pki.OraclePKIProvider()); //Security syntax
String url = "jdbc:oracle:thin:#(DESCRIPTION =\n" +
" (ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521))\n" +
" (CONNECT_DATA =\n" +
" (SERVER = DEDICATED)\n" +
" (SERVICE_NAME = sal)\n" +
" )\n" +
" )";
java.util.Properties props = new java.util.Properties();
props.setProperty("user", "system");
props.setProperty("password", "weblogic");
// props.setProperty("javax.net.ssl.trustStore","C:\\Users\\kcr\\Oracle\\WALLETS\\ewallet.p12");
// props.setProperty("oracle.net.ssl_cipher_suites","SSL_RSA_EXPORT_WITH_RC4_40_MD5");
// props.setProperty("javax.net.ssl.trustStoreType","PKCS12");
//props.setProperty("javax.net.ssl.trustStorePassword","welcome2");
DriverManager.registerDriver(new OracleDriver());
Connection conn = DriverManager.getConnection(url, props);
/*8 OracleDataSource ods = new OracleDataSource();
ods.setUser("system");
ods.setPassword("weblogic");
ods.setURL(url);
Connection conn = ods.getConnection();*/
Statement stmt = conn.createStatement();
ResultSet rset = stmt.executeQuery("select * from iris");
///////////////////////////
while(rset.next()) {
for (int i=1; i<=5; i++) {
System.out.print(rset.getString(i));
}
}
Are you expecting that your SELECT statement would return encrypted data and that your System.out.print calls would result in encrypted output going to the screen? If so, that's not the way advanced security works-- Advanced Security allows you to encrypt data over the wire but the data is unencrypted in the SQLNet stack. Your SELECT statement, therefore, would always see the data in an unencrypted state. You would need to do a SQLNet trace or use some sort of packet sniffer to see the encrypted data flowing over the wire.
You'll find the documentation in "SSL With Oracle JDBC Thin Driver".
In particular you should probably use PROTOCOL = TCPS instead of PROTOCOL = TCP. I'd also suggest using a stronger cipher suite (and avoid the anonymous ones, since with them you don't verify the identity of the remote server).

Resources