I have made database in SQL SERVER 2008 and have enabled the filestream technique. Now, how can I save the image to the SQL Server from vb 6.0. My database query for filesstream is as follows:
CREATE DATABASE Photo;
GO
ALTER DATABASE Photo
ADD FILEGROUP PhotoDBFS CONTAINS FILESTREAM;
GO
DECLARE #FilePath varchar(MAX) = (SELECT SUBSTRING(physical_name, 1, CHARINDEX(N'master.mdf', LOWER(physical_name)) - 1)
FROM master.sys.master_files
WHERE database_id = 1 AND file_id = 1) + 'PhotoDBFS_Filestream';
DECLARE #SQL varchar(MAX) = '
ALTER DATABASE Photo ADD FILE (
NAME = PhotoDBFSFile,
FILENAME = ''' + #FilePath + ''')
TO FILEGROUP PhotoDBFS;';
EXECUTE(#SQL);
GO
My table structure where I want to save the image is as follows:
CREATE TABLE Photos
(
PhotoId bigint NOT NULL PRIMARY KEY IDENTITY(1,1),
Title varchar(100) NOT NULL DEFAULT(''),
Subject varchar(100) NOT NULL DEFAULT('No Subject'),
Place varchar(100) NOT NULL DEFAULT('Unknown'),
Comment varchar(1000) NULL DEFAULT(''),
Rating tinyint NOT NULL DEFAULT(0),
PhotoFile varbinary(MAX) FILESTREAM NOT NULL,
CONSTRAINT PhotoRatingCheck CHECK(Rating >=0 AND Rating<=10)
);
My vb code for saving the image is as follows:
'Saving in the table [Photos]
Set Rs = New Recordset
SqlString = "SELECT * FROM Photos"
Rs.Open SqlString, con, adOpenStatic, adLockOptimistic, adCmdText
Rs.AddNew
Rs("UniqueId") = txtUniqueId.Text
Rs("CategoryId") = tempCategoryId
Rs("AlbumId") = tempAlbumId
Rs("Title") = txtTitle.Text
Rs("Subject") = txtSubject.Text
Rs("Place") = txtPlace.Text
Rs("Comment") = txtComment.Text
Rs("Rating") = sliderRating.Value
Rs("PhotoFile") = PhotoLocation
Rs.Close
Set Rs = Nothing
I get this error while saving.
Multiple-step OLE DB operation generated errors. check each OLE DB status value, if available. No work was done.
I also want to read the saved image from the database. Any suggestion???
You can't update IDENTITY columns, so remove assignment on UniqueId field, this fails now for certain.
When accessing the BLOB column PhotoFile sometimes helps to be explicit using Value property of the Field object i.e. Rs!PhotoFile.Value = binaryData or Rs("PhotoFile").Value = binaryData
For a table to have one or more FILESTREAM columns, it must also have a column of the uniqueidentifier data type that has the ROWGUIDCOL attribute. Does the CREATE TABLE statement you pasted in the question even work?
Related
hoping someone might be able to help me with a bit of an issue. Essentially i'm trying to get a rough size of all of the fields in my database as i'd like to do some math on it to guesstimate what the size will be with a compression technique applied to it.
I can do this for most fields by looking at the datatype and using the number of rows to get the number of bytes it's taking up. However on something like a varchar(max) field this is not as easy and so i decided to approach this by getting the average length within the column and multiplying by number of rows. But i've hit a snag which i'll describe below.
I have the following stored proc (i tried a function too but you can't call dynamic SQL from a function).
CREATE PROCEDURE dbo.getFieldSize(#column varchar(255), #table varchar(255), #ret decimal(15,7) OUTPUT)
AS
BEGIN
DECLARE #lengthSQL varchar(50)
/SET #lengthSQL = 'SELECT #ret = AVG(DATALENGTH(' + #column + ')) FROM [' + #table +']'/
SET #lengthSQL = 'SELECT #ret = AVG(DATALENGTH(' + #column + ')) FROM ' + #table
exec sp_executesql #lengthSQL
RETURN #ret
END
GO
And then i call it using...
SELECT b.TABLE_SCHEMA as 'Schema',
CASE WHEN DATA_TYPE IN ('nvarchar') AND CHARACTER_MAXIMUM_LENGTH <> -1 AND c.distinctItems <> 0 AND c.totalCount <> 0 THEN exec('select max(len(' + b.TABLE_CATALOG + ' + '.' + ' + b.COLUMN_NAME + '))')
FROM ....
The above is basically just checking to make sure it is a varchar(max) field and contains some values within the column. I then try and execute the SP and pass the column name and table name for which i need the avg length but i get the following error.
Msg 156, Level 15, State 1, Line 57
Incorrect syntax near the keyword 'exec'.
I learned you cannot call a dynamic SQL from a function and you cannot call a SP from a CASE statement. So at this point it seems like it's a catch 22 and i cannot do what i need using SQL. Can anyone think of any workarounds or i'm I out of luck on this?
Actually, you can do Dynamic SQL in a scalar UDF, it just needs to be a SQLCLR UDF ;-). But this is fairly simple to do using the in-process / internal connection (i.e. SqlConnection("Context Connection = true;");). Meaning, the assembly can be set to SAFE.
Also, object / column / index names are all NVARCHAR. And objects (if not also the others) are declared as sysname which is an alias for NVARCHAR(128). Just FYI.
So, something like the following (which I have tested and it does work):
[Microsoft.SqlServer.Server.SqlFunction(Name = "GetAvgBytes",
IsDeterministic = false, IsPrecise = true, DataAccess = DataAccessKind.Read)]
public static SqlInt32 GetAvgBytes([SqlFacet(MaxSize = 128)] SqlString TableName,
[SqlFacet(MaxSize = 128)] SqlString ColumnName)
{
int _AvgBytes = -1;
SqlConnection _Connection = new SqlConnection("Context Connection = true;");
SqlCommand _Command = _Connection.CreateCommand();
_Command.CommandType = CommandType.Text;
_Command.CommandText = "SELECT #AvgBytes = AVG(DATALENGTH(" + ColumnName.Value
+ ")) FROM " + TableName.Value + " WITH (NOLOCK);";
SqlParameter _Param = new SqlParameter("#AvgBytes", DbType.Int32);
_Param.Direction = ParameterDirection.Output;
_Command.Parameters.Add(_Param);
try
{
_Connection.Open();
_Command.ExecuteNonQuery();
_AvgBytes = (int)_Param.Value;
}
finally
{
_Connection.Close();
}
return _AvgBytes;
}
I have tried this code (ASP CLASSIC):
Public Function IsNullable(MyField)
Dim RS, SQL, Tmp
SQL = "SELECT " & MyField & " FROM mytable WHERE 1;"
Set RS = Server.CreateObject("ADODB.Recordset")
RS.Open SQL, conn 'I have connection opened elsewhere, using Driver={MySQL ODBC 5.2w Driver}
'Now check for Attributes
Tmp = RS.Fields(MyField).Attributes
IsNullable = 0 <> (Tmp And adFldIsNullable) '0x20
RS.Close
Set RS = Nothing
End Function
Function works fine but sometimes the result is wrong. For example it returns True for ID field, which is definitely not nullable as it is Primary Index Autoincrement. How can I make it relable?? Thanks
Added: It seems like when column is set to AutoIncrement Not Null then function works wrong...
It's by design according to http://bugs.mysql.com/bug.php?id=3857
[21 Jul 2004 22:26] Timothy Smith (Senior Support Engineer in those days)
This is because MySQL reports the DEFAULT value for such a column as NULL. It means, if you
insert a NULL value into the column, you will get the next integer value for the table's
auto_increment counter.
It is still valid and #kordirko's solution is quite acceptable.
In MySql you can query information_schema.columns view:
SELECT is_nullable
FROM information_schema.columns
WHERE table_schema = 'my_schema'
AND table_name = 'table-name'
AND column_name = 'column name'
see this demo: http://www.sqlfiddle.com/#!2/743d6/3
I m new to vb net
So here is my problem
My database has 1 table=quiz and 3 columns of ID ,name and Flag
All flags are set to '0'
Whenever I delete ,instead of deleting ,I update the name field to xxx and Flag to 1
In my database ,ID =3 has name = xxx
Still y is it entering the loop? and printing the msg"OH no"?
my code :
Dim SQL as String
SQL = "SELECT Name FROM quiz WHERE Flag='0' AND ID='3'"
c = 0
If SQL <> "xxx"Then
' Try, Catch, Finally
i = i + 1
MsgBox("Ohh no")
END IF
my table:
id address tag
1 test class1
2 test1 class2
3 test3 class3
In UI i am displaying all tag names as checkboxes.
When user selects one or more tag names then need to get required address values. how to get?
if user selects class1,class2 in UI then need to get test,test1 as result.
Please tell me how to write query in sqlserver 2008 for that.
EDIT CODE :
taglist = "class1,class2";
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["con"].ConnectionString);
SqlCommand cmd = new SqlCommand("usp_GetTags", con);
cmd.Parameters.Add("#Tags", SqlDbType.VarChar).Value = taglist;
con.Open();
cmd.CommandType = CommandType.StoredProcedure;
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);
while passing the parameters as above not getting any results.if i pass single taglist=class1 getting results.but taglist="class1,class2" not getting any resuls.please tell me how to pass multiple parameters from UI.
You can write the query in sql server by using the IN keyword.
Select address from mytable where tag IN ('class1','class2')
EDIT:
Add the parameters with values to the stored procedure like this. The below code is written in C#.net
comand.Parameters.AddWithValue("#Parameter1", "class1");
comand.Parameters.AddWithValue("#Parameter2", "class2");
EDIT 2:
Its very simple to put in a single string all the values, accordingly your query also suits that. Write the query in your stored procedure like
Select address from mytable where tag IN (#SingleParameter)
and in your coding part write like follow
string SingleParameter = "";
SingleParameter = "class1,class2,class3";
comand.Parameters.AddWithValue("#SingleParameter",SingleParameter);
EDIT 3:
Finally i found the solution for your problem. Write your stored procedure as below
ALTER PROCEDURE dbo.TestSP
/*
(
#parameter1 int = 5,
#parameter2 datatype OUTPUT
)
*/
#SingleParameter varchar(30)
AS
/* SET NOCOUNT ON */
declare #tags varchar(500)
set #tags = #SingleParameter
create table #t (tag varchar(10))
set #tags = 'insert #t select ' + replace(#tags, ',', ' union select ')
exec(#tags)
Select address from sample1 where (tag in (select tag from #t))
drop table #t
RETURN
and also send the parameters SingleParameter as below
string SingleParameter = "";
SingleParameter = "'class1','class2','class3'";
comand.Parameters.AddWithValue("#SingleParameter",SingleParameter);
I am working with MS-Access and JSP. I want to know that how can we create table with autonumber field and with primary key.
query="Create Table Registration_A (Reg_No PRIMARY KEY AUTOINCREMENT,
FName varchar(2))";
But its giving syntax error. What's the correct syntax?
CREATE TABLE Registration_A (
Reg_No AUTOINCREMENT,
FName VARCHAR(2),
CONSTRAINT RegA_PK PRIMARY KEY(Reg_No))
You can use the COUNTER keyword to create an AutoNumber field using DDL. I just tested this in a Java console app and it worked for me under both the JDBC-ODBC Bridge and UCanAccess:
String query =
"CREATE TABLE Registration_A (" +
"Reg_No COUNTER PRIMARY KEY, " +
"FName VARCHAR(2))";
Statement stmt = con.createStatement();
stmt.executeUpdate(query);
Seven years later, I don't see how to do this in DAO in any of the answers above or anywhere else on any Stack Exchange site. So here is the method I've worked out. The following VBA code creates a table with an autonumber field as primary key, puts some arbitrary data in it, then opens the table to show the results. I've run this code successfully in Access 2007.
Sub Make_Table_With_Autonum_Using_DAO()
Dim oDB As DAO.Database: Set oDB = CurrentDb()
Dim oTable As DAO.TableDef, sObjTable As String: sObjTable = "table_name"
Dim oField As DAO.Field, oIndex As DAO.Index
Dim oRS As DAO.Recordset
Set oTable = oDB.CreateTableDef(sObjTable)
With oTable
Set oField = .CreateField("ID_Object", dbLong) ' Create ID field.
oField.Attributes = dbAutoIncrField ' Make it autoincrement.
.Fields.Append oField ' Add to table's Fields collection.
Set oIndex = .CreateIndex("Index_Object") ' Create index.
oIndex.Primary = True ' Make it a primary key.
Set oField = oIndex.CreateField("ID_Object") ' Make index field for ID field.
oIndex.Fields.Append oField ' Add it to index's Fields coll'n.
.Indexes.Append oIndex ' Add index to table's Indexes coll'n.
Set oIndex = Nothing ' Remove index from memory.
Set oField = Nothing ' Remove field from memory.
.Fields.Append .CreateField("field2", dbText) ' Create and add other fields to
.Fields.Append .CreateField("field3", dbInteger) ' table's Fields collection.
' etc.
End With
oDB.TableDefs.Append oTable ' Add table to database's TableDefs collection.
Set oTable = Nothing
Set oRS = oDB.OpenRecordset(sObjTable) ' Enter arbitrary data into table.
oRS.AddNew: oRS!Field2 = "text 1": oRS!field3 = 123: oRS.Update
oRS.AddNew: oRS!Field2 = "text 2": oRS!field3 = 456: oRS.Update
oRS.AddNew: oRS!Field2 = "text 3": oRS!field3 = 789: oRS.Update
oRS.Close
DoCmd.OpenTable (sObjTable)
oDB.Close
Set oRS = Nothing
Set oDB = Nothing
End Sub
The Microsoft documentation for the necessary VBA elements, in order of appearance in the code, is:
TableDef.CreateField method (DAO)
Field.Attributes property (DAO)
Fields.Append method (DAO)
TableDef.CreateIndex method (DAO)
Index.Primary property (DAO)
Index.CreateField method (DAO)
Indexes.Append method (DAO)
That documentation says everything that needs to be known, but doesn't put it all together to explain how to make the autonumber primary key. The following MS documentation (no longer available directly from MS) does explain how to make the autonumber field, but not how to make it the primary key.
Programmatically Add Counter Field to Table Using DAO
In the following post on a Microsoft community forum, the accepted answer by Andrey Artemyev explains the whole thing.
Create a new table with AutoNumber field with VBA
My code above is essentially the same as his in that answer, with some additional commentary to explain what's going on.
This example uses ADOX to create a access table with an autonumber primary key
ADOX.Catalog cat = new ADOX.Catalog();
ADOX.Table table = new ADOX.Table();
ADOX.Key tableKey = new Key();
ADOX.Column col = new Column();
String connString = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=c:\test.accdb; Jet OLEDB:Database Password=";
cat.Create(ConnString);
// Define column with AutoIncrement features
col.Name = "ID";
col.Type = ADOX.DataTypeEnum.adInteger;
col.ParentCatalog = cat;
col.Properties["AutoIncrement"].Value = true;
table.Name = "Security";
table.Columns.Append(col); // default data type is text[255]
table.Columns.Append("Username", ADOX.DataTypeEnum.adVarWChar, 255);
table.Columns.Append("Password", ADOX.DataTypeEnum.adVarWChar, 255);
table.Columns.Append("Engineer", ADOX.DataTypeEnum.adBoolean);
table.Columns.Append("Default", ADOX.DataTypeEnum.adBoolean);
// Set ID as primary key
tableKey.Name = "Primary Key";
tableKey.Columns.Append("ID");
tableKey.Type = KeyTypeEnum.adKeyPrimary;
// Add table to database
cat.Tables.Append(table);
You need to mention the data type first, then the Primary Key.
query="Create Table Registration_A (Reg_No AUTOINCREMENT PRIMARY KEY, FName varchar(2))";
Try this On
Create Table Registration_A
(
Reg_No AUTOINCREMENT,
FName varchar(2),
PRIMARY KEY(Reg_No)
);
CREATE TABLE `Tablename` (Field1 AUTOINCREMENT CONSTRAINT `Primarykey` PRIMARY
KEY, `Field2` DATETIME, `Field3` TEXT(25), `Field4` DOUBLE);