Character width exceeded - sql

I create a master table with column A, column B, and column C. Whenever I try to insert row from another table using the command:
INSERT INTO MASTER
select * from Table B
I get the error message "Character Width exceeded". I am not sure why.

May be the one or more column size of Table B is larger than the respective column size of MASTER.
For e.g. - Table B's column1 might be VARCHAR(255) and MASTER's column A might be less than 255.

Check if the structure of table MASTER is exactly the same as the table B.
Probably is a problem in which MASTER.colx is a string(20) and B.colx is a string(25), or may be is a charset problem (unicode/latin-1/utf-8/iso-8859-x)

Consider creating the table MASTER as:
select *
into master
from tableB
where 1=0
This will guarantee that the column datatypes are the same between the two tables. Then you can try your insert again.

Related

BQ - INSERT without listing columns

I have 2 BQ tables, very wide ones in terms of number of columns. Note all the table columns are made nullable for flexibility
Table A - 1000 cols - Superset of Bs cols
Table B - 500 cols - Subset of As cols - exactly named/typed as above cols
So rows in Bs table data should be insertable into A, where anything column not inserted just gets a null. i.e 500 cols get a value, remaining 500 get a default null as not present in the insert.
So as these tables are very wide, enumerating all the columns in an insert statement would take forever and be a maintence nightmare.
Is there a way in standard SQL to insert without listing the columns names in the the insert statement, whereby its automagically name matched?
So I want to be able to do this really and have the columns from B matched to A for each row inserted? If not is there any other way I am not seeing that could help with this?
thanks!
INSERT INTO
`p.d.A` (
SELECT
*
FROM
`p.d.B` )
I actually tried enumerating the columns to see if nesting worked and seems it doesnt?
INSERT INTO
`p.d.A` (x, y.z) (
SELECT
x, y.z
FROM
`p.d.B` )
I cant just say (x,y) as y structs from the dff tables arent exactly the same BQ complains structs dont match exact.....hence why I was trying y.z ?
Sure, easy!
Prepare dummy table p.d.b_ using below select
SELECT * FROM `p.d.a` WHERE FALSE
(Note, even though result will be empty table - above will scan whole table a - this is required just once - so should be Okey - if not you can script this once and just create this table from script)
Ok, so now instead of using
SELECT * FROM `p.d.b`
you will use
SELECT * FROM `p.d.b*`
and this will make a trick for you (it did for me :o)
P.S. Of course I assume you will make sure there is no other tables with names starting with b (or whatever real name is) in that dataset

How copy one table contents to another, ignoring PK duplicates when i don't know column set

I have 2 databases: SRC and DST. Each one contains table DATA an in every database DATA's columns sets are equal, but it's unknown for user (I don't know name of PK or even is PK identity or single).
I already have the following script:
insert into DST.dbo.DATA select * from SRC.dbo.DATA
But if DST.DATA contains rows with same PK it throws an error (I'm using C#). That's why i want to use something like
on duplicate ignore
from mysql
Could you please advice me script that copies rows from SRC.dbo.DATA to DST.dbo.DATA ignoring primary key constraints. And if possible, foreign constraints too
Sorry for bad english
You can try something like
insert into DST.dbo.DATA
select s.*
from SRC.dbo.DATA s LEFT JOIN
DST.dbo.DATA d ON s.Keys1 = d.Keys1
AND s.Keys2 = d.Keys2
...
AND s.KeysN = d.KeysN
WHERE d.Keys1 IS NULL
This should allow you to only insert values from Source, that is not in Destination.
You can try something like this, to not select from SRC which is existing in DST.
insert into DST.dbo.DATA select * from SRC.dbo.DATA
WHERE SRC.dbo.DATA.PKColumn NOT IN(SELECT PKColumn FROM DST.dbo.DATA)

Sql Column had no values

I have a sql table that I am trying to add a column from another table to. Only when I execute the alter table query it does not pull the values out of the table to match the column where I am trying to make the connection.
For example I have column A from table 1 and column A from table 2, they are supposed to coincide. ColumnATable1 being an identification number and ColumnATable2 being the description.
I tried this but got an error...
alter table dbo.CommittedTbl
add V_VendorName nvarchar(200)
where v_venkey = v_vendorno
It tells me that I have incorrect syntax... Anyone know how to accomplish this?
alter table dbo.CommittedTbl
add V_VendorName nvarchar(200);
go
update c
set c.V_VendorName = a.V_VendorName
from CommittedTbl c
join TableA a
on c.v_venkey = a.v_vendorno;
go
I'm just guessing at your structure here.
alter table 2 add column A <some_type>;
update table2 set column A = (select column_A from table2 where v_venkey = v_vendorno);
Your names for tables and columns are a bit confusing but I think that should do it.
There is no WHERE clause for an ALTER TABLE statement. You will need to add the column (your first two lines), and then insert rows based upon a relationship you define between the two tables.
ALTER TABLE syntax:
http://msdn.microsoft.com/en-us/library/ms190273%28v=sql.90%29.aspx
There are several languages within SQL:
DDL: Data Definition Language - this defines the schema (the structure of tables, columns, data types) - adding a column to a table affects the table definitions and all rows will have that new column (not just some rows according to a criteria)
DML: Data Manipulation Language - this affects data within a table, and inserting, updating or other changes fall into this and you can update some data according to criteria (and this is where a WHERE clause would come in)
ALTER is a DDL statement, while INSERT and UPDATE are DML statements.
The two cannot really be mixed as you are doing.
You should ALTER your table to add the column, then INSERT or UPDATE the column to include appropriate data.
Is it possible that you want a JOIN query instead? If you want to join two tables or parts of two tables you should use JOIN.
have a look at this for a start if you need to know more LINK
hope that helps!

How to fix this stored procedure problem

I have 2 tables. The following are just a stripped down version of these tables.
TableA
Id <pk> incrementing
Name varchar(50)
TableB
TableAId <pk> non incrementing
Name varchar(50)
Now these tables have a relationship to each other.
Scenario
User 1 comes to my site and does some actions(in this case adds rows to Table A). So I use a SqlBulkCopy all this data in Table A.
However I need to add the data also to Table B but I don't know the newly created Id's from Table A as SQLBulkCopy won't return these.
So I am thinking of having a stored procedure that finds all the id's that don't exist in Table B and then insert them in.
INSERT INTO TableB (TableAId , Name)
SELECT Id,Name FROM TableA as tableA
WHERE not exists( ...)
However this comes with a problem. A user at any time can delete something from TableB so if a user deletes say a row and then another user comes around or even the same user comes around and does something to Table A my stored procedure will bring back that deleted row in Table B. Since it will still exist in Table A but not Table B and thus satisfy the stored procedure condition.
So is there a better way of dealing with two tables that need to be updated when using bulk insert?
SQLBulkCopy complicates this so I'd consider using a staging table and an OUTPUT clause
Example, in a mixture of client pseudo code and SQL
create SQLConnection
Create #temptable
Bulkcopy to #temptable
Call proc on same SQLConnection
proc:
INSERT tableA (..)
OUTPUT INSERTED.key, .. INTO TableB
SELECT .. FROM #temptable
close connection
Notes:
temptable will be local to the connection and be isolated
the writes to A and B will be atomic
overlapping or later writes don't care about what happens later to A and B
emphasising the last point, A and B will only ever be populated from the set of rows in #temptable
Alternative:
Add another column to A and B called sessionid and use that to identify row batches.
One option would be to use SQL Servers output clause:
INSERT YourTable (name)
OUTPUT INSERTED.*
VALUES ('NewName')
This will return the id, name of the inserted rows to the client, so you can use them in the insert operation for the second table.
Just as an alternative solution you could use database triggers to update the second table.

Combine two columns together from separate tables

Let's say for instance:
I have two tables: old_data and new_data.
Both old_data and new_data have one column called this_is_col.
Both old_data and new_data have various (hundreds) of rows of dates (2010-02-06, 2010-01-09, 2007-06-02, etc.). Both tables don't necessarily have the same dates, but they both have the same format.
The fields of both tables are various integers.
My task:
Copy the fields from old_data to new_data.
If a date exists in both tables, the field in new_data will be replaced.
If the date doesn't exist in new_data, then the correct row will be added and the field will be copied over.
Here is how far I've gotten:
Create a temporary column:
ALTER TABLE `new_data` ADD `tempColumn` TEXT NULL;
Copy over data from old_data:
INSERT INTO `new_data` (`tempColumn`) SELECT `this_is_col` FROM `old_data`;
Combine temporary column and new_data . this_is_col. (I haven't really figured this step out since I haven't gotten this far).
MERGE? `tempColumn` `this_is_col`;
Delete temporary table
ALTER TABLE `new_data` DROP `tempColumn`;
Upon performing the second action (transferring the data over to the temporary column) I get this error:
#1062 - Duplicate entry '0000-00-00' for key 1
And now I'm stuck. Any help would be appreciated. I'm using MySQL and phpMyAdmin to test the SQL commands.
Assuming your dates are indexed as unique keys:
INSERT INTO newtable
SELECT *
FROM oldtable
ON DUPLICATE KEY column1=oldcolumn1, ...
you want INSERT ... ON DUPLICATE KEY UPDATE. your solution already satisfies steps 1 and 3 of your task, ON DUPLICATE KEY UPDATE will take care of step 2.
If you'd rather delete the row first, instead of updating: REPLACE
It'd be just one line too, so: REPLACE data SELECT, you wouldn't have to do the weirdness with adding a text column.
How about just doing an UPDATE and INSERT?
UPDATE new_data SET col=col
FROM new_data a join old_data b on a.this_is_col = b.this_is_col
Then
INSERT INTO new_data (cols) SELECT cols
FROM old_data WHERE this_is_col NOT IN (SELECT this_is_col FROM new_data)
Unless I misunderstood...